c – 由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< int,double,char>.不幸的是,g 7.2和g trunk失败了静态断言. clang 5.0.0和clang trunk按预期编译和工作.

godbolt.org conformance view

这是一个g bug吗?或者,为什么不应该遵循演绎指南?

在构造函数上添加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

两者都是有效的(类型……在第一种情况下可以推断为空),但这里的调用应该是模糊的 – 既不比另一种更专业.类型…不参与此处的订购(类似于[temp.deduct.partial]/12中的示例).因此,正确的行为是进入下一个决胜局,即favors deduction-guides.因此,这应该是一个列表< int,char>.

但是,gcc的行为是支持构造函数,因此static_assert触发器因为类型……在那种情况下确实是空的.

相关文章

文章浏览阅读315次。之前用C语言编过链表,这几天突然想用C+...
文章浏览阅读219次。碰到问题就要记录下来,防止遗忘吧。文章...
文章浏览阅读1.8k次,点赞11次,收藏37次。因为自己对决策树...
文章浏览阅读492次。C++ 设计模式之策略模式
文章浏览阅读683次。我也算是个C++的小白,对于C++中的谓语我...
文章浏览阅读225次。又看了一遍操作符的东西,感觉之前对操作...