c++ - std::enable_if 跨编译器的不同行为(取决于外部类模板参数)
问题描述
我有一个嵌套的 ( Inner
) 类,我想要一个构造函数,这取决于封闭类 ( ) 有enable_if
多少模板参数 ( ) 。Args
Outer
我想出了下面的代码,只是发现它在某些编译器上编译得很好,而在某些编译器上却没有。
#include <tuple>
#include <type_traits>
template <typename... Args>
struct Outer {
struct Inner {
Inner(const Outer* out, Args... vals)
: outer(out)
, values(vals...)
{}
// This ctor should be enabled only if Args are non-empty
template <typename = std::enable_if_t<(sizeof...(Args) > 0)>>
Inner(const Outer* out)
: outer(out)
{}
const Outer* outer;
std::tuple<Args...> values;
};
};
int main()
{
Outer<int, int> o1;
Outer<int, int>::Inner i1(&o1, 1, 2);
Outer<int, int>::Inner i11(&o1);
Outer<> o2;
Outer<>::Inner i2(&o2);
Outer<>::Inner i21(nullptr);
}
显示在 Godbolt 上:https ://godbolt.org/z/lsivO9
有趣的部分是结果:
GCC 8.2 -std=c++17
- 编译失败GCC trunk -std=c++17
- 好的MSVC 19.14 /std:c++17 /permissive-
- 好的MSVC 19.16 /std:c++17 /permissive-
- 好的clang 7 -std=c++17
- 编译失败clang trunk -std=c++17
- 编译失败
所以,问题:
- 类的 是
Args...
在Outer
类的直接上下文中Inner
吗? - 上面的例子格式正确吗?
- 哪个编译器是对的?
- 为什么 GCC 开始对主干表现不同?
解决方案
You need to make std::enable_if
dependent on the constructor template parameter
template <std::size_t N = sizeof...(Args), std::enable_if_t<(N > 0), bool> = true>
Inner(const Outer* out)
: outer(out)
{}
推荐阅读
- joomla - Joomla 规范网址错误
- excel - Excel QR 生成问题 - & +
- laravel - 自动登录在laravel 6中成功注册后出现错误
- python - 如何使用 Python 3 和 pandas 从多个 Excel 工作表中提取和组合相同的行号?
- c++ - 静态结构和一个定义规则
- php - PHP - 我如何将 X-CSRF-TOKEN 放在标题中?
- python - Jupyter Lab 自动 nbconvert 到 python 设置?
- python - 此代码是否从文件中读取前 10000 行?
- android - 为什么 Xamarin Android 无法发送 GRPC/Http2 请求?
- c++ - 对 C 宏的未定义引用,但在我定义它时出现重新定义错误