为什么 sfinae 过载没有解决
why sfinae overload is not resolved
这个版本工作正常:
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; }
};
与:
error: 'template template V Foo2::bar()' cannot be overloaded with 'template template V Foo2::bar()'
两个版本的区别在于第一个版本我直接使用表达式,第二个版本我创建一个模板默认参数并将其用作 return 类型。
第二个例子失败的原因是什么?
因为在case#2中,两个bar
被认为是等价的。当consider whether two function templates are equivalent or not时,忽略默认模板参数;它们不是函数模板签名的一部分。所以他们被认为是
template<typename U, typename V>
V bar() { std::cout << "1" << std::endl; }
template<typename U, typename V>
V bar() { std::cout << "2" << std::endl; }
如你所见,它们实际上是等价的。
(强调我的)
Two function templates are considered equivalent if
- they are declared in the same scope
- they have the same name
- they have identical template parameter lists
- the expressions involving template parameters in their return types and parameter lists are equivalent
案例#1 有效,因为 return 类型依赖于模板参数并与不同的表达式一起使用;那么他们就被认为是不等价的。
这个版本工作正常:
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; }
};
与:
error: 'template template V Foo2::bar()' cannot be overloaded with 'template template V Foo2::bar()'
两个版本的区别在于第一个版本我直接使用表达式,第二个版本我创建一个模板默认参数并将其用作 return 类型。
第二个例子失败的原因是什么?
因为在case#2中,两个bar
被认为是等价的。当consider whether two function templates are equivalent or not时,忽略默认模板参数;它们不是函数模板签名的一部分。所以他们被认为是
template<typename U, typename V>
V bar() { std::cout << "1" << std::endl; }
template<typename U, typename V>
V bar() { std::cout << "2" << std::endl; }
如你所见,它们实际上是等价的。
(强调我的)
Two function templates are considered equivalent if
- they are declared in the same scope
- they have the same name
- they have identical template parameter lists
- the expressions involving template parameters in their return types and parameter lists are equivalent
案例#1 有效,因为 return 类型依赖于模板参数并与不同的表达式一起使用;那么他们就被认为是不等价的。