C++模板专门化除一种类型外的所有类型

C++ template specialization all types except one

本文关键字:类型 一种 专门化 C++      更新时间:2023-10-16

我需要一个方法(C++11),它可以为除一个类型之外的所有类型调用。

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

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

有几种方法可以做到这一点,因此您可以使用最方便的方法:

// 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是过滤掉类型的一些子集

您不需要模板专门化。和SFINAE(enable_if)。当您陷入模板函数时,很容易忘记函数可能会过载。只需创建一个非模板重载,当传递精确类型的参数时,就会优先使用该重载(链接文章中提供了更好的解决方案):

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

我强烈建议阅读这篇文章为什么不专门化函数模板?赫伯·萨特。

道德#1:如果你想自定义一个函数库模板参与过载解决的自定义(或总是在完全匹配的情况下使用),使其成为一个普通的旧函数,而不是专门化。而且,如果你确实提供了过载,避免同时提供专业化。

但你陷入了道德#2:

但如果你是一个编写而不仅仅是使用函数的人呢样板你能做得更好,避免这个(和其他)问题吗为您自己和您的用户?确实可以:

道德#2:如果你正在编写一个函数库模板,更喜欢将其作为一个单一的函数模板编写专门化或重载,然后实现函数模板完全作为一个简单的切换到包含静态具有相同签名的函数。每个人都可以专门从事这两项工作完全和部分,并且不影响过载的结果决议

完整的解释在文章中。

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

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

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

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

相关文章: