C++ 如何检查函数的模板参数是否具有某种类型?

C++ 如何检查函数的模板参数是否具有某种类型?,c++,templates,typechecking,C++,Templates,Typechecking,假设我有一个模板类型为T的函数和另外两个类a和B 模板 无效函数(常数T&T) { ........... //检查T==A是否做某事 ........... //检查T==B是否执行其他操作 } 如何进行这两项检查(不使用Boost库)?如果您想对某些参数类型使用func的特殊实现,只需为该类型创建一个特定的重载: template <typename T> void func(const T & t) { // generic code } void func(

假设我有一个模板类型为T的函数和另外两个类a和B

模板
无效函数(常数T&T)
{
...........
//检查T==A是否做某事
...........
//检查T==B是否执行其他操作
}

如何进行这两项检查(不使用Boost库)?

如果您想对某些参数类型使用
func
的特殊实现,只需为该类型创建一个特定的重载:

template <typename T>
void func(const T & t) {
   // generic code
}

void func(const A & t) {
   // code for A
}
模板
无效函数(常数T&T){
//通用代码
}
无效函数(常数A&t){
//密码
}

创建具有专门化的函数模板,这将实现您想要的功能

template <class T>
void doSomething() {}

template <>
void doSomething<A>() { /* actual code */ }

template <class T>
void doSomeOtherThing() {}

template <>
void doSomeOtherThing<B>() { /* actual code */ }

template <typename T>
void func(const T & t)
{
    ...........
    //check if T == A do something
    doSomething<T>();
    ...........
    //check if T == B do some other thing
    doSomeOtherThing<T>();
}
模板
void doSomething(){}
模板
void doSomething(){/*实际代码*/}
模板
void doSomeOtherThing(){}
模板
void doSomeOtherThing(){/*实际代码*/}
模板
无效函数(常数T&T)
{
...........
//检查T==A是否做某事
doSomething();
...........
//检查T==B是否执行其他操作
doSomeOtherThing();
}

如果你真的只想用一个布尔值来测试
T==a
,那么你可以使用
is same
,在C++11中作为
std::is_same
提供,或者在TR1之前作为
std::TR1::is_same

const bool T_is_A = std::is_same<T, A>::value;
const bool T_is_A=std::is_same::value;
您可以自己编写这个小类:

template <typename, typename> struct is_same { static const bool value = false;};
template <typename T> struct is_same<T,T> { static const bool value = true;};
模板结构是相同的{static const bool value=false;};
模板结构是相同的{static const bool value=true;};

通常情况下,您可能会发现将分支代码打包到专门用于
A
B
的单独类或函数中更为方便,因为这将为您提供编译时条件。相比之下,只能在运行时检查
if(T_is_A)

如果您完全省略了主模板的定义,
template void doSomething()a
也不是
B
@KerrekSB:实际上,在这种情况下,不管
T
,都会出现编译时错误,因为专门化将无法找到其主模板。这就是为什么两者都包括在内:)事实上,你必须省略一般定义,为
doSomething
doSomething
添加一个不做任何事情的定义。是的,我把OP的问题误读为打开
T
的“开关”,但这并不是真正要求的。没关系:-S@SteveJessop:是的,但语义会略有不同。它将需要一个实际的
T
作为参数(这不是问题,OP可能无论如何都想使用它),并且它将专门处理
T
不是
a
,但可转换为
T
(或
T&
,取决于您如何操作)。您的意思是,只在运行时完成
是相同的::value
是一个整数常量表达式。中的代码,如果(T_is_A)很可能在一个体面的编译器中被删除死代码,这会在运行之前发生。问题是这两个分支中的代码在被删除之前都必须编译。@SteveJessop:嗯,优化是一个细节。。。不过,主要的一点是,正如您所说,所有分支代码都必须是有效代码,这是一个相当大的限制。相比之下,专门化的模板不需要有意义,除非它们被实际实例化。与已经提出的模板相比,这种解决方案具有优势,因为如果“做点什么”和“做点别的”将变量定义为double,将变量定义为int,函数专门化技术将不起作用,因为这些变量将是这些函数的局部变量。谢谢你的解决方案!
template <typename, typename> struct is_same { static const bool value = false;};
template <typename T> struct is_same<T,T> { static const bool value = true;};