Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何检查模板类是否属于特定的类类型?_C++_Templates - Fatal编程技术网

C++ 如何检查模板类是否属于特定的类类型?

C++ 如何检查模板类是否属于特定的类类型?,c++,templates,C++,Templates,在我的模板化函数中,我试图检查T类型是否为特定类型。我该怎么做 p/s我知道模板规范的方法,但我不想这样做 template<class T> int foo(T a) { // check if T of type, say, String? } 模板intfoo(ta){ //检查T是否为类型,例如字符串? } 谢谢 而不是检查类型使用专门化。否则,不要使用模板 template<class T> int foo(T a) { // generic

在我的模板化函数中,我试图检查T类型是否为特定类型。我该怎么做

p/s我知道模板规范的方法,但我不想这样做

template<class T> int foo(T a) {
  // check if T of type, say, String?
}
模板intfoo(ta){
//检查T是否为类型,例如字符串?
}

谢谢

而不是检查类型使用专门化。否则,不要使用模板

template<class T> int foo(T a) {
      // generic implementation
}
template<> int foo(SpecialType a) {
  // will be selected by compiler 
}

SpecialType x;
OtherType y;
foo(x); // calls second, specialized version
foo(y); // calls generic version
模板intfoo(ta){
//通用实现
}
模板int foo(特殊类型a){
//将由编译器选择
}
特殊类型x;
其他类型y;
foo(x);//调用第二个专用版本
foo(y);//调用通用版本

如果你真的想避免专门化,你可以检查using(例如
是相同的
是可转换的
)。

我想你可以使用typeid操作符返回的

如果你不关心编译时间,你可以使用

bool isString=boost::is_same::value;
从C++11开始,它现在是标准库的一部分

bool isString = std::is_same<T, std::string>::value
bool isString=std::值是否相同

您可以对收到的类型执行静态检查(查看boost type traits库),但除非您在某个点使用专门化(或重载,正如@litb正确指出的那样),否则您将无法根据参数类型提供不同的特定实现

除非您有特殊的原因(您可以添加到问题中)不在接口中使用专门化,否则只需进行专门化

template <> int subtract( std::string const & str );
模板int减法(std::string const&str);

我想应该有人告诉你为什么避免使用重载或专门化可能不是一个好主意。考虑:

template<class T> int foo(T a) {
  if(isAString<T>()) {
    return a.length();
  } else {
    return a;
  }
}
您还可以更好地为不同的行为路径分离代码。这一切不再是一成不变的。请注意,重载时,参数可能具有不同的类型形式,如果两者匹配得一样好,编译器仍将使用正确的版本,这里就是这样:一个可以是引用,而另一个不能


嗯,因为我有很大一部分 相同的代码,直到“规范” 部分

可以使用重载,但是如果大部分代码都适用于任何类型,则可以考虑将不同的部分提取到单独的函数中,并将其重载。

template <class T>
void specific(const T&);

void specific(const std::string&);

template <class T>
void something(const T& t)
{
    //code that works on all types
    specific(t);
    //more code that works on all types
}
模板
特定空隙(常数T&);
特定于void(const std::string&);
模板
使某物无效(常数T&T)
{
//适用于所有类型的代码
特异性(t);
//更多适用于所有类型的代码
}

如果您使用的是C++11或更高版本,std::is_same会完全满足您的要求:

template <typename T>
constexpr bool IsFloat() { return std::is_same<T, float>::value; }

template <typename T>
void SomeMethodName() {
  if (IsFloat<T>()) {
    ...
  }
}
模板
constexpr bool IsFloat(){return std::is_same::value;}
模板
void SomeMethodName(){
if(IsFloat()){
...
}
}

为什么不使用“模板规范方式”?使用“模板重载方式”:)您可能应该检查行为,不是type.hmm,因为在“规范”部分之前,我有很大一部分相同的代码。如果需要检查T的类型,您使用模板的方式是错误的。我认为您应该重新考虑您的方法。在我看来,这就是我需要的。谢谢!将尝试超越警告:运行时检查。因此,您不能依赖编译时属性。例如,在检查t==std::string之后,不能只使用
运算符[]
。@huy通常最好对类型进行静态检查,而不是运行时检查。因此,
std::是相同的
std::是可转换的
,或类似的。这样就可以避免检查类型的运行时开销。相反,如果只有部分代码需要知道类型,请使用
if constexpr
(C++17)或助手函数;如果你的代码都是这样,那么就使用函数重载。我遇到了你前面提到的问题,这就是为什么我想找到一种解决方法,但不需要重载或类专门化。我没有想到“了解事情将如何运作”这一部分。我会重新考虑的,谢谢!用cast修改您的示例就可以了。但这仍然不是我最喜欢的解决办法:)@Ben,你的意思是什么把戏?在哪里插入演员阵容?你的意思是写
重新解释cast(&i)->length()
?我同意那会很难看。如果
T
std::string
,它仍然会在另一个分支中失败,因为它无法将其转换为
int
(返回类型)。也不是我最喜欢的解决方案:)最好重载或专门化它。这就是C++17
如果constexpr
是什么for@DanielH不幸的是,
如果编写此答案时constexpr
不存在。因此,如果现在可以使用constexpr使第一个示例有效,那么说“
更为正确”。尽管也许这应该是另一个答案,而不仅仅是一个注释?作为记录:它现在是标准库的一部分。“如果你不关心编译时间”你是指编译代码所花费的时间,还是能够在编译时检测到“相同性”?专门化函数模板通常是个坏主意;不支持部分专门化,如果将专门化和重载混合在一起,通常会得到意外的结果。从一开始就超负荷。
template <class T>
void specific(const T&);

void specific(const std::string&);

template <class T>
void something(const T& t)
{
    //code that works on all types
    specific(t);
    //more code that works on all types
}
template <typename T>
constexpr bool IsFloat() { return std::is_same<T, float>::value; }

template <typename T>
void SomeMethodName() {
  if (IsFloat<T>()) {
    ...
  }
}