如何检查我的模板类是否具有特定的类型?

时间:2010-02-15 10:54:16

标签: c++ templates

在我的模板化功能中,我正在尝试检查类型T是否为特定类型。我该怎么做?

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

template<class T> int foo(T a) {
  // check if T of type, say, String?
}

谢谢!

8 个答案:

答案 0 :(得分:49)

而不是检查类型使用特化。否则,请勿使用模板。

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

答案 1 :(得分:13)

如果您不关心编译时,可以使用boost::is_same

bool isString = boost::is_same<T, std::string>::value;

从C ++ 11开始,它现在是标准库的一部分

bool isString = std::is_same<T, std::string>::value

答案 2 :(得分:11)

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

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

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
}

答案 3 :(得分:7)

我想你可以使用typeid运算符

返回的std::type_info

答案 4 :(得分:6)

我怀疑有人应该告诉你为什么不使用重载或专业化不是一个好主意。考虑:

template<class T> int foo(T a) {
  if(isAString<T>()) {
    return a.length();
  } else {
    return a;
  }
}

您可能会第一眼看到它也适用于int,因为它只会尝试为length调用字符串。但这种直觉是错误的:即使在运行时没有采用该分支,编译器仍会检查字符串分支。如果T是int,它会发现你试图在非类上调用成员函数。

如果您需要不同的行为,那么您应该将代码分开。但是更好地使用重载而不是专门化,因为它更容易弄清楚事情是如何工作的。

template<class T> int foo(T a) {
  return a;
}

int foo(std::string const& a) {
  return a.length();
}

您还可以更好地分离不同行为路径的代码。它不再是全部了。请注意,使用重载时,参数可能具有不同的类型形式,如果两者都匹配良好,编译器仍将使用正确的版本,如下所示:一个可以是引用,而另一个不能。

答案 5 :(得分:4)

如果您真的想避免专业化,可以使用type_traits (available in Boost and TR1)(例如is_sameis_convertible)进行检查。

答案 6 :(得分:2)

您可以对收到的类型执行静态检查(查看boost类型特征库),但除非您在某个时刻使用特化(或重载,如@litb正确指出),否则您不会能够根据参数类型提供不同的特定实现。

除非您有特殊原因(可以添加到问题中),否则不要在界面中使用专业化,只需要专门化。

template <> int subtract( std::string const & str );

答案 7 :(得分:1)

如果您使用的是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>()) {
    ...
  }
}

http://en.cppreference.com/w/cpp/types/is_same