考虑以下代码:
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)
to be list<int, double, char>
。很遗憾,g++ 7.2 and g++ 主干静态断言失败。铿锵++ 5.0.0 and 铿锵++树干编译并按预期工作。
godbolt.org 一致性视图 https://godbolt.org/g/XScFjS
这是一个g++漏洞?或者是否有一个原因推演指南不应该在这里遵循吗?
在构造函数上添加 SFINAE 约束似乎提供了所需的行为:
template <typename... Args,
typename = std::enable_if_t<sizeof...(Args) == sizeof...(Types)>>
list(Args...)
{
static_assert(sizeof...(Types) > 0);
}
godbolt.org 一致性视图 https://godbolt.org/g/Kk5fJH
This is 海湾合作委员会错误 80871 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80871。问题是,我们最终得到了这组候选推导:
template <class... Types, class... Args>
list<Types...> __f(Args... ); // constructor
template <class... Args>
list<Args...> __f(Args... ); // deduction-guide
两者均有效(Types...
在第一种情况下可以推断为空),但这里的调用应该是不明确的 - 两者都不比另一个更专业。Types...
这里不参与订购(类似中的例子[温度扣除部分]/12 http://eel.is/c++draft/temp.deduct.partial#12)。所以正确的行为是进入下一个决胜局,即有利于演绎指南 http://eel.is/c++draft/over.match.best#1.10。因此,这应该是一个list<int, double, char>
.
然而,gcc 的行为有利于构造函数,因此static_assert
触发因为Types...
在那种情况下确实会是空的。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)