【问题标题】:Auto non-type template parameter with user defined types具有用户定义类型的自动非类型模板参数
【发布时间】:2018-06-21 18:25:39
【问题描述】:

在这个video 27:35 Bryce Lelbach 给出了以下示例:

template<auto... Dims>
struct dimensions {};

struct dynamic_extent {};
constexpr dynamic_extent dyn = {};

dimensions<64, dyn, 32> d;

此代码无法编译。 GCC 抱怨:

<source>:8:27: error: 'struct dynamic_extent' is not a valid type for a template non-type parameter
     dimensions<64, dyn, 32> d;
                           ^

Clang 抱怨:

<source>:8:20: error: a non-type template parameter cannot have type 'dynamic_extent'
    dimensions<64, dyn, 32> d;
                   ^
<source>:2:22: note: template parameter is declared here
    template<auto... Dims>
                     ^

他的例子是不是完全错误(这很奇怪,因为他提到了一个使用这个想法的库)或者我没有得到什么?

【问题讨论】:

    标签: c++ templates c++17


    【解决方案1】:

    是的,他的例子是错误的。

    P0732 之前,非类型模板参数不能具有类类型,这是 C++20 的一个特性。即使在 C++20 中,这仍然格式错误,因为要选择使用 dyn 作为非类型模板参数,您需要:

    struct dynamic_extent {
        auto operator<=>(dynamic_extent ) = default;
    };
    

    到那时,它会起作用的。


    我猜他的意思是:

    dimensions<64, &dyn, 32> d;
    //             ^^^^
    

    传递该指针很好 - 指针在 C++17(以及更早的版本)中是可接受的非类型模板参数,只要它们满足一些其他要求 - dyn 可以。

    【讨论】:

      【解决方案2】:

      那个例子是错误的。这在 C++17 中不起作用。 Non-type template parameters 必须是以下之一:

      • std::nullptr_t
      • 积分型
      • 左值引用类型(对象或函数)
      • 指针类型(指向对象或函数)
      • 指向成员类型的指针(指向成员对象或成员函数)
      • 枚举类型

      任意类类型不在此列表中。


      请注意,使用枚举作为标签类型是可行的:

      template<auto... Dims>
      struct dimensions {};
      
      enum class dynamic_extent {};
      constexpr dynamic_extent dyn = {};
      
      dimensions<64, dyn, 32> d;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-03-28
        • 1970-01-01
        • 2018-05-01
        • 1970-01-01
        • 2014-08-19
        • 2018-05-15
        • 2023-01-25
        • 2014-09-16
        相关资源
        最近更新 更多