C++ std::enable_if的不同编译器行为(取决于外部类模板参数)
我有一个嵌套的(C++ std::enable_if的不同编译器行为(取决于外部类模板参数),c++,c++11,templates,gcc,enable-if,C++,C++11,Templates,Gcc,Enable If,我有一个嵌套的(internal)类,我想根据封闭类(Outer)有多少模板参数(Args)为其启用构造函数 我想出了下面的代码,结果发现它在某些编译器上编译得很好,而在某些编译器上编译得不好 #包括 #包括 样板 结构外部{ 结构内部{ 内部(常量外部*外部,参数…VAL) :外部(外部) ,值(VAL…) {} //仅当参数为非空时,才应启用此ctor 模板> 内部(常数外部*外部) :外部(外部) {} 常量外部*外部; std::tuple 有趣的是结果: GCC 8.2-std=c+
internal
)类,我想根据封闭类(Outer
)有多少模板参数(Args
)为其启用构造函数
我想出了下面的代码,结果发现它在某些编译器上编译得很好,而在某些编译器上编译得不好
#包括
#包括
样板
结构外部{
结构内部{
内部(常量外部*外部,参数…VAL)
:外部(外部)
,值(VAL…)
{}
//仅当参数为非空时,才应启用此ctor
模板>
内部(常数外部*外部)
:外部(外部)
{}
常量外部*外部;
std::tuple
有趣的是结果:
GCC 8.2-std=c++17
-编译失败
GCC trunk-std=c++17
-正常
MSVC 19.14/std:c++17/permissive-
-OK
MSVC 19.16/std:c++17/permissive-
-OK
clang7-std=c++17
-编译失败
clangtrunk-std=c++17
-编译失败
因此,问题是:
外部
类的参数…
是否在内部
类的直接上下文中
- 上面的例子格式正确吗
- 哪个编译器是对的
- 为什么GCC开始在trunk上表现出不同的行为
如果依赖于构造函数模板参数,则需要使std::enable\u
template <std::size_t N = sizeof...(Args), std::enable_if_t<(N > 0), bool> = true>
Inner(const Outer* out)
: outer(out)
{}
template=true>
内部(常数外部*外部)
:外部(外部)
{}
SFINAE仅适用于SFINAE依赖于函数模板参数的函数。这里不是。因此,硬错误是正确的
这可能是一种不需要诊断的情况,而您的程序仍然是病态的(因此编译器可以自由地做任何事情)。解决这个问题很棘手,因为有一个简单的解决方法,您不妨这样做
template <std::size_t N = sizeof...(Args), typename = std::enable_if_t<(N > 0)>>
当Args…
为空时,我看不出这一点。非常感谢,它在所有使用template>
的编译器上都有效。我还感兴趣的是MSVC是否正确,或者说GCC在主干上是否有一个回归。@sthlm58-GCC主干仍在开发中。std::enable\u if
在运行时有效为模板构造函数而不是类指定类型;MSVC是错误的。
template <typename = std::enable_if_t<false>>
Inner(const Outer* out)
template <std::size_t N = sizeof...(Args), typename = std::enable_if_t<(N > 0)>>
template <std::size_t N = sizeof...(Args), std::enable_if_t<(N > 0), bool> = true>
Inner(const Outer* out, Args... vals)
: outer(out)
, values(vals...)
{}