我需要一个为所有类型调用的方法(C ++ 11)。
template<typename T>
void method(T& value)
{
...
}
template<>
void method(std::string& value)
{
...
}
有可能做这样的事吗?如果没有,除了在运行时使用typeid还有其他选择吗?
答案 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 ++类型特征(在另一个答案中回答)。