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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2265381/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 22:46:32  来源:igfitidea点击:

How do I check my template class is of a specific classtype?

c++templates

提问by huy

In my template-ized function, I'm trying to check the type T is of a specific type. How would I do that?

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

p/s I knew the template specification way but I don't want to do that.

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

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

Thanks!

谢谢!

采纳答案by sergiom

I suppose you could use the std::type_inforeturned by the typeid operator

我想你可以使用std::type_infotypeid 运算符返回的

回答by dirkgently

Instead of checking for the type use specializations. Otherwise, don't use templates.

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

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

回答by Beno?t

If you don't care about compile-time, you may use boost::is_same.

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

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

As of C++11, this is now part of the standard library

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

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

回答by visitor

hmm because I had a large portion of same code until the 'specification' part.

嗯,因为在“规范”部分之前我有很大一部分相同的代码。

You can use overloading, but if a large part of the code would work for any type, you might consider extracting the differing part into a separate function and overload that.

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

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
}

回答by Johannes Schaub - litb

I suspect someone should tell you why it might not be a good idea to avoid using overloading or specialization. Consider:

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

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

You might think on a first sight that it will work for inttoo, because it will only try to call lengthfor strings. But that intuition is wrong: The compiler still checks the string branch, even if that branch is not taken at runtime. And it will find you are trying to call a member function on non-classes if Tis an int.

乍一看,您可能会认为它也适用int,因为它只会尝试调用length字符串。但这种直觉是错误的:编译器仍会检查字符串分支,即使在运行时未采用该分支。并且它会发现您正在尝试在非类上调用成员函数 ifT是 int。

That's why you should separate the code if you need different behavior. But better use overloading instead of specialization, since it's easier to get a clue how things work with it.

这就是为什么如果您需要不同的行为,您应该将代码分开。但是最好使用重载而不是专业化,因为更容易了解事情是如何工作的。

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

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

You have also better separated the code for different paths of behavior. It's not all anymore clued together. Notice that with overloading, the parameters may have different type forms and the compiler will still use the correct version if both match equally well, as is the case here: One can be a reference, while the other can not.

您还更好地分离了不同行为路径的代码。不再一概而论。请注意,通过重载,参数可能具有不同的类型形式,如果两者匹配得同样好,编译器仍将使用正确的版本,就像这里的情况:一个可以是引用,而另一个则不能。

回答by kennytm

You can check using type_traits(available in Boost and TR1)(e.g. is_sameor is_convertible) if you really want to avoid specialization.

如果您真的想避免专业化,您可以检查 using type_traits(在 Boost 和 TR1 中可用)(例如is_sameis_convertible)。

回答by David Rodríguez - dribeas

You can perform static checks on the type that you have received (look at the boost type traits library), but unless you use specialization (or overloads, as @litb correctly points out) at one point or another, you will not be able to provide different specific implementations depending on the argument type.

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

Unless you have a particular reason (which you could add to the question) not to use the specialization in the interface just do specialize.

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

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

回答by Dave Dopson

If you are using C++11 or later, std::is_same does exactly what you want:

如果您使用的是 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

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