杂数演绎指南不是由 g++ 采取的,由 clang++ 采取 - 谁是正确的
Variadic deduction guide not taken by g++, taken by clang++ - who is correct?
请考虑以下代码:
template <typename... Types>
struct list
{
template <typename... Args>
list(Args...)
{
static_assert(sizeof...(Types) > 0);
}
};
template <typename... Args>
list(Args...) -> list<Args...>;
int main()
{
list l{0, 0.1, 'a'};
}
我希望decltype(l)
是list<int, double, char>
.不幸的是,g++ 7.2 和 g++ 主干无法实现静态断言。clang++ 5.0.0 和 clang++ 主干编译并按预期工作。
godbolt.org 一致性视图
这是一个 g++ 错误吗?还是有理由不在这里遵循扣除指南?
在构造函数上添加 SFINAE 约束似乎提供了所需的行为:
template <typename... Args,
typename = std::enable_if_t<sizeof...(Args) == sizeof...(Types)>>
list(Args...)
{
static_assert(sizeof...(Types) > 0);
}
godbolt.org 一致性视图
这是 gcc 错误 80871。问题是,我们最终得到了这组要扣除的候选人:
template <class... Types, class... Args>
list<Types...> __f(Args... ); // constructor
template <class... Args>
list<Args...> __f(Args... ); // deduction-guide
两者都是有效的(在第一种情况下Types...
可以推断为空),但这里的调用应该是模棱两可的 - 两者都不比另一个更专业。 Types...
不参与此处的排序(类似于 [temp.deduct.partial]/12 中的示例)。因此,正确的行为是进入下一个决胜局,这有利于演绎指南。因此,这应该是一个list<int, double, char>
。
但是,gcc的行为是支持构造函数,因此static_assert
触发器,因为在这种情况下Types...
确实是空的。
相关文章:
- 奇怪的结构&GCC&clang(void*返回类型)
- 数据成员SFINAE的C++17测试:gcc vs clang
- 当我编译webrtc服务器时,Windows上只支持clang-cl
- 为什么在Windows上的VS 2019和Clang 9中"size_t"在没有标题的情况下工作
- 我可以将一个用clang c++11编译的对象与另一个用c++17编译的对象链接起来吗
- Clang bug?使用指针作为模板参数
- clang整洁10忽略了我的NOLINT命令
- 如何防止clang格式在流运算符调用之间添加换行符<<
- 在clang++预处理器中确定gcc工具链版本
- 为什么 Clang 不允许"and"作为函数名称?
- 带有 -stdlib=libc++ 的 clang++ 9.0.1 找不到<optional>
- clang格式:宏的缩进
- CLANG 编译器 说:变量"PTR"可能未初始化
- clang格式:禁用排序包含
- 为什么lambda在clang上崩溃而不是在gcc上崩溃
- gcc和clang在表达式是否为常量求值的问题上存在分歧
- 循环展开 - G++ 与 Clang++
- 如何使用Clang/GCC在Mac上为C/C++设置VSCode
- 一位朋友将模板函数缩写为clang和gcc
- 杂数演绎指南不是由 g++ 采取的,由 clang++ 采取 - 谁是正确的