gpt4 book ai didi

c++ - g++ 不采用的可变参数推导指南,clang++ 采用 - 谁是正确的?

转载 作者:IT老高 更新时间:2023-10-28 22:21:26 26 4
gpt4 key购买 nike

考虑以下代码:

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.2g++ trunk 未能通过静态断言。 clang++ 5.0.0clang++ trunk 编译并按预期工作。

godbolt.org conformance view

这是一个 g++ 错误吗?还是这里不应该遵循演绎指南的原因?


在构造函数上添加 SFINAE 约束似乎提供了所需的行为:

template <typename... Args, 
typename = std::enable_if_t<sizeof...(Args) == sizeof...(Types)>>
list(Args...)
{
static_assert(sizeof...(Types) > 0);
}

godbolt.org conformance view

最佳答案

这是gcc bug 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 中的示例)。所以正确的行为是进行下一个决胜局,favors deduction-guides .因此,这应该是 list<int, double, char> .

然而,gcc 的行为是有利于构造函数,因此 static_assert触发因为 Types...在那种情况下确实是空的。

关于c++ - g++ 不采用的可变参数推导指南,clang++ 采用 - 谁是正确的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46848129/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com