c++ - enable_if 在返回类型中没有 decltype 失败
问题描述
我有一个函数的 3 个重载,每个重载由enable_if
struct thing{
typedef int data_type;
template <typename T, int N = 0, typename = typename std::enable_if<N == 0 && std::is_same<T, data_type>::value>::type>
data_type data() { return 1; }
template <typename T, int N = 0, typename = typename std::enable_if<N == 0 && !std::is_same<T, data_type>::value>::type>
auto data() { return 0; }
template <typename T, int N, typename = typename std::enable_if<N != 0>::type>
auto data() { return -1; }
};
上面的代码编译失败,报错
test.cpp:12:10: error: ‘template<class T, int N, class> auto thing::data()’ cannot be overloaded with ‘template<class T, int N, class> auto thing::data()’
12 | auto data() { return -1; }
| ^~~~
test.cpp:10:10: note: previous declaration ‘template<class T, int N, class> auto thing::data()’
10 | auto data() { return 0; }
这些函数中的每一个都可以通过第三个模板参数相互区分。SFINAE失败的原因是什么?
另一方面,以下工作
template <typename T, int N = 0, typename = typename std::enable_if<N == 0 && !std::is_same<T, data_type>::value>::type>
auto data() { return 0; }
template <typename T, int N, typename = typename std::enable_if<N != 0>::type>
decltype(auto) data() { return -1; }
并返回正确的结果
thing t;
std::cout << "t.data<int>(): " << t.data<int>() << std::endl; // 1
std::cout << "t.data<double>(): " << t.data<double>() << std::endl; // 0
std::cout << "t.data<int, 1>(): " << t.data<int, 1>() << std::endl; // -1
std::cout << "t.data<double, 1>(): " << t.data<double, 1>() << std::endl; // -1
在这种情况下为什么以及如何decltype
提供帮助?
解决方案
默认(模板)参数不是签名的一部分,
它应该是
struct thing{
typedef int data_type;
template <typename T, int N = 0, typename std::enable_if<N == 0 && std::is_same<T, data_type>::value, int>::type = 0>
data_type data() { return 1; }
template <typename T, int N = 0, typename std::enable_if<N == 0 && !std::is_same<T, data_type>::value, int>::type = 0>
auto data() { return 0; }
template <typename T, int N, typename std::enable_if<N != 0, int>::type = 0>
auto data() { return -1; }
};
推荐阅读
- three.js - 纹理几何在照明更新时丢失图像
- python - Python/Pydantic - 使用带有 json 对象的列表
- intellij-idea - 有没有办法以独立于大小写(然而,各自)的方式选择和编辑下一个事件?
- java - 如何在java中的变量中使用大数进行算术运算而不会出现异常
- r - R cron 脚本不会自动刷新 httr-oauth 令牌
- reactjs - 为什么 React 组件不是每次都重新渲染?
- jquery - 有没有办法在外部点击时关闭 UIkit 切换?
- javascript - 在不同的域中设置 localStorage
- javascript - Javascript:在 Chrome 和 Firefox 中解析 unicode 字符串会产生不同的结果
- javascript - 我试图在向该对象添加新属性之前将对象推送到数组,但它直接更新数组