#include <type_traits>
template<bool b>
struct S
{
template<typename = std::enable_if_t<b>>
S() {}
template<typename = std::enable_if_t<!b>>
S(int) {}
};
S<true> s{}; // error in clang/gcc, OK in VC2017
S<false> s{0}; // error in clang/gcc, OK in VC2017
Run Code Online (Sandbox Code Playgroud)
在这两种情况下,clang/gcc尝试实例化由于SFINAE而实际应该丢弃的ctor.错误消息是:
错误:'std :: enable_if <false,void>'中没有名为'type'的类型; 'enable_if'不能用于禁用此声明
clang/gcc对另一个ctor的实例化是不正确的,因为它不应该在可能的重载列表中,对吧?
但在我提交错误之前,我想阅读别人的想法.也许我说得不对劲......
Rak*_*111 11
这是MSVC中的一个错误; clang和gcc是对的.
问题是SFINAE仅在过载分辨率期间发生,而不是之前.我的意思是,如果函数在你调用它之前是不正确的,那就是错误.
S<true>例如,当您使用时,将实例化整个类.它看起来有点像这样:
struct S_true
{
template<typename = void>
S() {}
template<typename = /*fail*/>
S(int) {}
};
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,第二个构造函数是完全错误的,它不是有效的定义,因为没有type找到类型(因为std::enable_if).因此SFINAE甚至无法启动,类定义是错误的并且被诊断出来.
您需要将模板参数b作为两个构造函数的模板参数列表的一部分(请查看@ bolov的答案).
@ Rakete1111 100%正确.
您需要使模板参数bool b成为两个构造函数的模板参数列表的一部分.
以下是如何做到这一点(这是一种非常标准的技术):
template<bool b>
struct S
{
template<bool bb = b, typename = std::enable_if_t<bb>>
S() {}
template<bool bb = b, typename = std::enable_if_t<!bb>>
S(int) {}
};
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
375 次 |
| 最近记录: |