Условие типа в шаблоне
Возможно ли построить только часть кода, заданного типом шаблона в С++?
Было бы что-то озеро:
#include <iostream>
using namespace std;
template<typename T>
void printType(T param)
{
#if T == char*
cout << "char*" << endl;
#elif T == int
cout << "int" << endl;
#else
cout << "???" << endl;
#endif
}
int main()
{
printType("Hello world!");
printType(1);
return 0;
}
Ответы
Ответ 1
Типовые черты:
#include <iostream>
#include <type_traits> // C++0x
//#include <tr1/type_traits> // C++03, use std::tr1
template<typename T>
void printType(T param)
{
if(std::is_same<T,char*>::value)
std::cout << "char*" << endl;
else if(std::is_same<T,int>::value)
std::cout << "int" << endl;
else
std::cout << "???" << endl;
}
Или еще лучше, просто перегрузите функцию:
template<class T>
void printType(T partam){
std::cout << "???" << endl;
}
void printType(char* partam){
std::cout << "char*" << endl;
}
void printType(int partam){
std::cout << "int" << endl;
}
Частичное упорядочение позаботится о том, чтобы вызывалась правильная функция. Кроме того, перегрузка предпочтительна для специализации шаблонов в общем случае, см. this и это искусство для почему. Можете не претендовать на вас, если вам нужно полностью напечатать тип, поскольку неявные преобразования рассматриваются для перегруженных функций.
Ответ 2
Использовать специализированную специализацию:
template<typename T>
void printType(T param)
{
// code for the general case - or omit the definition to allow only the specialized types
}
template<>
void printType<char*>(char* param)
{
// code for char*
}
template<>
void printType<int>(int param)
{
// code for int
}
// ...
Ответ 3
Вы можете использовать специализацию. Препроцессор работает перед всеми шаблонами и не может взаимодействовать с ними.
template<typename T> void printType(T t) {
std::cout << typeid(T).name(); // fallback
}
template<> void printType<char*>(char* ptr) {
std::cout << "char*";
}
template<> void printType<int>(int val) {
std::cout << "int";
}
Ответ 4
Вы используете спецификацию шаблона, чтобы указать версии вашей функции для работы по-разному в зависимости от ее типа. Например, вы можете создать универсальную версию функции, которая будет работать с большинством типов, и создать определенную версию, например. int
, что будет быстрее. Вы бы сделали это следующим образом:
template <class T>
void printType(T param)
{
cout<<"Generic version"<<endl;
}
template <>
void printType<int>(int param)
{
cout<<"Int version"<<endl;
}
template <>
void printType<char>(char param)
{
cout<<"Char version"<<endl;
}
//Rince and repeat.
Ответ 5
Так как С++ 17 есть способ сделать именно это с if-constexpr. Следующие компиляции, поскольку clang-3.9.1, gcc-7.1.0 и недавний MSVC-компилятор 19.11.25506 отлично справляются с опцией /std: С++ 17.
#include <iostream>
#include <type_traits>
template<typename T>
void printType(T)
{
if constexpr (std::is_same_v<T, const char*>)
std::cout << "const char*" << std::endl;
else if constexpr (std::is_same_v<T, int>)
std::cout << "int" << std::endl;
else
std::cout << "???" << std::endl;
}
int main()
{
printType("Hello world!");
printType(1);
printType(1.1);
return 0;
}
Вывод:
const char*
int
???