我最近遇到了一些编译错误,归结为以下虚拟示例。基本上我正在构建一个&#34; plus2&#34;功能模板,我希望它仅适用于 int 和 float 。从逻辑上讲,当&#34; is_numerical&#34;类型特质测试通过。但是在编译错误C2782 / C2784 / C2676抱怨将<2>添加到 字符串 时会挂起。
该示例仅供参考,没有意义。更重要的是,编写这种逻辑的正确方法是什么?感谢。
#include <iostream>
#include <string>
using namespace std;
template <typename T>
struct is_numerical {
static const bool value = false;
};
template <>
struct is_numerical<float> {
static const bool value = true;
};
template <>
struct is_numerical<int> {
static const bool value = true;
};
template <typename T>
T plus2(T input) {
if (is_numerical<T>::value) {
return input + 2;
} else { return input; }
}
int main()
{
//char x('a'); // prints 'a'
string x("a"); // compiler error
cout << plus2(x) << endl;
return 0;
}
答案 0 :(得分:2)
问题是当T input
是std::string
时,您仍在尝试编译return input + 2;
。 即使它位于始终为false
的if语句中。
在C ++ 17中,if constexpr
允许有条件编译的代码。
template <typename T>
T plus2(T input) {
if constexpr (is_numerical<T>::value) {
return input + 2;
} else { return input; }
}
在C ++的所有标准化版本中,SFINAE也可以防止无效代码被编译。
template <typename T>
T plus2(T input, typename std::enable_if<! is_numerical<T>::value>::type* = 0) {
return input;
}
template <typename T>
T plus2(T input, typename std::enable_if<is_numerical<T>::value>::type* = 0) {
return input + 2;
}
答案 1 :(得分:0)
你需要像函数签名的这一部分而不是正文那样进行测试。如果函数签名匹配,编译器将尝试实例化它,但此时它会失败。
template<typename T>
T plus@2( value, typename std::enable_if<is_numeric<T>::value>::type * = nullptr)
{
return value + 2;
}
请注意,如果您尝试传递测试失败的内容,则会得到一个&#34;没有匹配的签名&#34;类型错误。