C ++模板专门化除了一个以外的所有类型

时间:2017-01-26 06:56:44

标签: c++ c++11 templates

我需要一个为所有类型调用的方法(C ++ 11)。

template<typename T>
void method(T& value)
{
...
}

template<>
void method(std::string& value)
{
...
}

有可能做这样的事吗?如果没有,除了在运行时使用typeid还有其他选择吗?

3 个答案:

答案 0 :(得分:5)

有几种方法可以做到这一点,所以你可以使用最方便的方法:

// way 1
template<typename T, 
         typename std::enable_if<!std::is_same<T,std::string>::value>::type* = nullptr>
// way 2
void method(T& value)
{
    static_assert(!std::is_same<T,std::string>::value,"std::string is not accepted");
    ...
}

// way 3
template <>
void method<std::string>(std::string&) = delete; 

至于我,我发现3是最方便的过滤掉特定类型的,1是过滤掉某些类型的子集

答案 1 :(得分:2)

您不需要模板专业化。而且SFINAE(enable_if)都没有。当您遇到模板功能时,很容易忘记功能可能会超载。只需创建一个非模板化的重载,并在传递确切类型的参数时进行优化(链接文章中提供了更好的解决方案):

template<typename T>
void method(T& value)
{
  // ...
}

void method(std::string& value)
{
  // ...
}

我强烈建议您阅读Herb Sutter撰写的这篇文章Why Not Specialize Function Templates?

  

道德#1:如果你想自定义一个功能基础模板并且想要   参与重载决策的定制(或者,到   总是在完全匹配的情况下使用),使它变得简单   功能,而不是专业化。而且,如果你提供过载,   避免提供专业化。

但你属于道德#2:

  

但是,如果你是一个写作的人,而不仅仅是使用一个函数,那该怎么办?   模板?你能做得更好,避免这个(和其他)问题   前,为自己和用户?的确,你可以:

     道德#2:如果您正在编写功能库模板,更喜欢   把它写成一个永远不应该的单一功能模板   专门或重载,然后实现功能模板   完全作为包含静态的类模板的简单切换   具有相同签名的功能。每个人都可以专注于这两者   完全和部分,并且不会影响过载的结果   分辨率。

整篇文章都在文章中。

答案 2 :(得分:0)

这是基本的模板专业化,请看下面的代码示例。

代码示例(基于您的代码):

template<typename T>
void method(T& value) {
    //
}

template<>
void method<std::string>(std::string& value) {
    //
}

这意味着,当您使用std :: string参数调用方法时,将调用第二个(专用)方法。否则,如果你不想拥有第二个函数,那么你将不得不使用c ++类型特征(在另一个答案中回答)。