C ++类型特征虚拟示例:编译器错误

时间:2018-01-05 17:41:39

标签: c++ templates typetraits

我最近遇到了一些编译错误,归结为以下虚拟示例。基本上我正在构建一个&#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;
}

2 个答案:

答案 0 :(得分:2)

问题是当T inputstd::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;类型错误。