c++ - 为什么 sfinae 过载没有解决
问题描述
这个版本工作正常:
template<typename T>
struct Foo
{
template<typename U = T>
typename std::enable_if<std::is_same<U,A>::value>::type
bar() { std::cout << "1" << std::endl; }
template<typename U = T>
typename std::enable_if<std::is_same<U,B>::value>::type
bar() { std::cout << "2" << std::endl; }
};
此版本失败:
template<typename T>
struct Foo2
{
template<typename U = T, typename V = typename std::enable_if<std::is_same<U,A>::value>::type >
V bar() { std::cout << "1" << std::endl; }
template<typename U = T, typename V = typename std::enable_if<std::is_same<U,B>::value>::type >
V bar() { std::cout << "2" << std::endl; }
};
和:
错误:“模板模板 V Foo2::bar()”不能用“模板模板 V Foo2::bar()”重载
两个版本之间的区别在于第一个我直接使用表达式,第二个我创建一个模板默认参数并将其用作返回类型。
第二个例子失败的原因是什么?
解决方案
因为在案例#2 中,两者bar
被认为是等价的。在考虑两个函数模板是否等价时,默认模板参数被忽略;它们不是函数模板签名的一部分。所以他们被认为是
template<typename U, typename V>
V bar() { std::cout << "1" << std::endl; }
template<typename U, typename V>
V bar() { std::cout << "2" << std::endl; }
如您所见,它们实际上是等价的。
(强调我的)
两个函数模板被认为是等效的,如果
- 它们在同一范围内声明
- 他们有相同的名字
- 他们有相同的模板参数列表
- 在其返回类型和参数列表中涉及模板参数的表达式是等价的
case#1 有效,因为返回类型取决于模板参数并与不同的表达式一起使用;那么它们被认为是不等价的。
推荐阅读
- html - href滚动锚angularjs
- c++ - 访问除 main.cpp 之外的 .cpp 文件中的 QMLEngine /rootObject 属性
- java - 有人可以解释如下代码吗?
- java - 为什么 Jedis 比 spring redisTemplate 快?
- css - 缩放取决于浏览器分辨率/浏览器屏幕大小
- pytest - pytest的交错重复
- sql - 如果存在,则超过主键中的重复值
- javascript - 神经进化 - func 不是函数错误
- jquery - 在 Postcodes.io 中返回 JSON 值
- vba - Outlook 宏,用于保存来自特定人员/以特定标题开头的邮件的附件