Variadic deduction guide not taken by g++, taken by clang++ - who is correct?(g++ 不采用可变参数推导指南,clang++ 采用-谁是正确的?)
问题描述
考虑以下代码:
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.不幸的是,g++ 7.2 和 g++ trunk 未能通过静态断言.clang++ 5.0.0 和 clang++ trunk 编译并按预期工作.
I would expect decltype(l) to be list<int, double, char>. Unfortunately, g++ 7.2 and g++ trunk fail the static assertion. clang++ 5.0.0 and clang++ trunk compile and work as expected.
godbolt.org 一致性视图
这是一个 g++ 错误吗?或者有什么理由不应该在这里遵循演绎指南?
Is this a g++ bug? Or Is there a reason why the deduction guide should not be followed here?
在构造函数上添加 SFINAE 约束似乎提供了所需的行为:
Adding a SFINAE constraint on the constructor seems to provide the desired behavior:
template <typename... Args,
typename = std::enable_if_t<sizeof...(Args) == sizeof...(Types)>>
list(Args...)
{
static_assert(sizeof...(Types) > 0);
}
godbolt.org 一致性视图
推荐答案
这是 gcc 错误 80871.问题是,我们最终得到了这组推演的候选对象:
This is gcc bug 80871. The issue is, we end up with this set of candidates for deduction:
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.
Both are valid (Types... can deduce as empty in the first case), but the call here should be ambiguous - neither is more specialized than the other. Types... does not participate in ordering here (similar to the example in [temp.deduct.partial]/12). So the correct behavior is to proceed to the next tiebreaker, which favors deduction-guides. Hence, this should be a list<int, double, char>.
然而,gcc 的行为是有利于构造函数,因此 static_assert 触发器因为 Types... 在这种情况下确实是空的.
However, gcc's behavior is to favor the constructor, hence the static_assert triggers becuase Types... would indeed be empty in that situation.
这篇关于g++ 不采用可变参数推导指南,clang++ 采用-谁是正确的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:g++ 不采用可变参数推导指南,clang++ 采用-谁是正
基础教程推荐
- 如何将 std::pair 的排序 std::list 转换为 std::map 2022-01-01
- 如何通过C程序打开命令提示符Cmd 2022-12-09
- 在 C++ 中计算滚动/移动平均值 2021-01-01
- 静态库、静态链接动态库和动态链接动态库的 .lib 文件里面是什么? 2021-01-01
- 常量变量在标题中不起作用 2021-01-01
- 如何在 C++ 中初始化静态常量成员? 2022-01-01
- C++结构和函数声明。为什么它不能编译? 2022-11-07
- 我有静态或动态 boost 库吗? 2021-01-01
- 这个宏可以转换成函数吗? 2022-01-01
- 如何检查GTK+3.0中的小部件类型? 2022-11-30
