C++模板专门化除一种类型外的所有类型
C++ template specialization all types except one
我需要一个方法(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++类型的特性(在另一个答案中回答)。
相关文章:
- 有没有一种方法可以通过"typedef"为重新定义的基本类型定义特征和强制转换运算符
- 在运行时检查继承是否只有一种类型和 void*
- 文本冒险游戏 - 如何区分一种项目类型与另一种项目类型以及如何构建项目类/子类
- 当 c++ 需要一种数据类型并获取另一种数据类型时会发生什么?
- 在硬件SIMD矢量指针和相应类型之间进行"interpret_cast"是一种未定义的行为吗
- 另一种类型的智能ptr,比如具有弱refs的unique_ptr
- void* 数组将元素转换为另一种类型
- 使用字节向量作为其他类型的原始存储是一种好的做法吗
- 将一种数据类型的向量复制到同一数据类型的结构向量中的有效方法是什么
- 将一种类型的比特重新解释为不同类型的比特的技术
- 有没有一种方法可以使用SFINAE来检测一个类型是否实现了给定的抽象基类
- 在枚举类型上使用std::max是不是一种糟糕的做法
- 为什么需要类型名称,即使似乎足以推断名称应该是一种类型?
- 在 c++ 中将一种结构类型分配给另一种类型
- 将空基类优化对象强制转换为另一种类型是否会破坏严格的别名?
- 我怎样才能让编译器推导出一种类型的 nullptr
- 如何测试指针类型是否可以安全地转换为另一种指针类型?
- 有没有一种很好的方法来实现具有默认失败情况的条件类型?
- 一种类型的多个 cv 分解
- 如何将对象定义为一种类型,然后再将其声明为子类型