SFINAE for class 成员函数(一个编译另一个不编译)
SFINAE for class member function (one compiles the other not)
为什么 class A
编译而 class B
不编译,编译器抱怨有两个声明,不是都依赖 SFINAE 吗?
在使用 foo
?
时,两者实际上都应该使用模板类型推导
所以真正的问题是,这两个版本有什么细微的不同
为什么 class A
成功使用 sfinae...?
- Class A 使用 默认值(零)annonymous(不需要)non -类型
模板参数
- Class B 使用 type-defaulted (with enable_if) annonymous 类型 模板参数
代码:
template<typename T>
struct A
{
template<typename U,
typename std::enable_if<!std::is_floating_point<U>::value>::type * = nullptr
>
void foo() {}
template<typename U,
typename std::enable_if<std::is_floating_point<U>::value>::type * = nullptr
>
void foo() {}
};
template<typename T>
struct B
{
template<typename U,
typename = typename std::enable_if<!std::is_floating_point<U>::value>::type
>
void foo() {}
template<typename U,
typename = typename std::enable_if<std::is_floating_point<U>::value>::type
>
void foo() {}
};
在class B
中,两个foo
具有相同的签名(即使它们的默认值不同):
template <typename U, typename Dummy>
void foo();
所以 class B.
的错误
在classA中,字面上的类型是不同的(即使它们都以void
结尾)
§1.3.22 定义函数模板的签名:
signature
<
class member function template>
name, parameter type list (8.3.5), class of which the function is a member,
cv-qualifiers (if any), ref-qualifier (if any), return type, and
template parameter list
模板参数列表不包括给定的默认参数。对于 A::foo
,模板参数不等效(在 §14.5.6.1 中精确定义的术语)。在 B::foo
,他们是。您只是用不同的默认参数声明相同的函数模板——因此违反了 §9.2/1 和 §14.1/12。
这是仅通过 enable_if
的条件重载函数模板时的常见问题。特别是对于构造函数,您不能将 enable_if
部分放在 return 值中。
为什么 class A
编译而 class B
不编译,编译器抱怨有两个声明,不是都依赖 SFINAE 吗?
在使用 foo
?
所以真正的问题是,这两个版本有什么细微的不同
为什么 class A
成功使用 sfinae...?
- Class A 使用 默认值(零)annonymous(不需要)non -类型 模板参数
- Class B 使用 type-defaulted (with enable_if) annonymous 类型 模板参数
代码:
template<typename T>
struct A
{
template<typename U,
typename std::enable_if<!std::is_floating_point<U>::value>::type * = nullptr
>
void foo() {}
template<typename U,
typename std::enable_if<std::is_floating_point<U>::value>::type * = nullptr
>
void foo() {}
};
template<typename T>
struct B
{
template<typename U,
typename = typename std::enable_if<!std::is_floating_point<U>::value>::type
>
void foo() {}
template<typename U,
typename = typename std::enable_if<std::is_floating_point<U>::value>::type
>
void foo() {}
};
在class B
中,两个foo
具有相同的签名(即使它们的默认值不同):
template <typename U, typename Dummy>
void foo();
所以 class B.
的错误在classA中,字面上的类型是不同的(即使它们都以void
结尾)
§1.3.22 定义函数模板的签名:
signature
<
class member function template>
name, parameter type list (8.3.5), class of which the function is a member, cv-qualifiers (if any), ref-qualifier (if any), return type, and template parameter list
模板参数列表不包括给定的默认参数。对于 A::foo
,模板参数不等效(在 §14.5.6.1 中精确定义的术语)。在 B::foo
,他们是。您只是用不同的默认参数声明相同的函数模板——因此违反了 §9.2/1 和 §14.1/12。
这是仅通过 enable_if
的条件重载函数模板时的常见问题。特别是对于构造函数,您不能将 enable_if
部分放在 return 值中。