【问题标题】:gcc internal error when using variadic concept template使用可变参数概念模板时的 gcc 内部错误
【发布时间】:2017-11-21 22:20:12
【问题描述】:

我最近玩弄了gcc 中的概念功能,并在类的构造函数或成员函数中使用可变参数概念模板时偶然发现了这个错误:

template<typename From, typename To>
concept bool ConvertibleNoNarrow = requires(From f, To t) {
    t = { f };
};

class Foo
{
public:
    template<ConvertibleNoNarrow<double>... Args>
    Foo(Args&&... args) { /*...*/ }
};

使用Foo时,gcc显示内部错误:

err.cpp: In substitution of ‘template<class ... Args>  requires  ConvertibleNoNarrow<Args, double>... Foo::Foo(Args&& ...) [with Args = {double}]’:
err.cpp:23:11:   required from here
err.cpp:13:3: internal compiler error: in tsubst_constraint, at cp/constraint.cc:1956
   Foo(Args&&... args) { }
   ^~~

如果在全局函数中使用相同的签名,一切都会按预期工作:

/* works */    
template<ConvertibleNoNarrow<double>... Args>
void Test(Args&&... args) { }

任何人都可以重现这种情况或知道为什么会发生这种情况以及如何调用现有的错误报告吗?

编辑:

我的 gcc 版本:

gcc (Gentoo 7.2.0 p1.1) 7.2.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

【问题讨论】:

标签: c++ gcc


【解决方案1】:

这是 gcc (bugzilla link) 中的一个错误。

不过,您可以通过在requires 子句中添加约束来解决此问题。因此,我们检查每种类型的概念并相应地返回std::true_typestd::false_type。通过这样做,我们可以使用std::conjunction_v和参数包扩展来独立约束每个类型。

class Foo
{
public:
    template<typename... Args>
        requires std::conjunction_v<std::conditional_t
            < ConvertibleNoNarrow<Args, double>
            , std::true_type
            , std::false_type
            >...>
    Foo(Args&&... args) { /*...*/ }
};

【讨论】:

    【解决方案2】:

    类似于@nyronium 的回答,但更简单一点,您可以在 requires 子句中使用折叠表达式。

    class Foo
    {
    public:
        template<typename... Args>
            requires (ConvertibleNoNarrow<Args, double> && ...)
        Foo(Args&&... args) { /*...*/ }
    };
    

    我在 GCC 7.3.0 上测试了等效项。

    【讨论】:

      猜你喜欢
      • 2019-11-23
      • 1970-01-01
      • 2014-02-01
      • 1970-01-01
      • 2021-02-17
      • 2021-12-26
      • 2016-06-05
      • 1970-01-01
      • 2020-05-14
      相关资源
      最近更新 更多