代码之家  ›  专栏  ›  技术社区  ›  Evg

具有用户定义类型的自动非类型模板参数

  •  7
  • Evg  · 技术社区  · 6 年前

    在这 video 27∶35 布莱斯勒巴赫 给出以下示例:

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

    此代码无法编译。海合会投诉:

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

    叮当抱怨道:

    <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>
                         ^
    

    他的例子是完全错误的(这很奇怪,因为他指的是一个图书馆,这个想法被使用)还是我没有得到什么?

    2 回复  |  直到 6 年前
        1
  •  6
  •   Justin    6 年前

    那个例子是错误的。这在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;
    
        2
  •  8
  •   Community c0D3l0g1c    6 年前

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

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

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

    在那一点上,它会起作用的。


    我想他的意思是:

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

    传递指针是很好的——指针在C++ 17中是可接受的非类型模板参数(并且更早),只要它们满足一些其他的要求 戴恩 做。