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

时间:2018-06-21 18:25:39

标签: c++ templates c++17

在{em> 27:35 的video中,
布莱斯·莱尔巴赫给出了以下示例:

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

C语抱怨:

<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 个答案:

答案 0 :(得分:8)

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

P0732(C ++ 20功能)之前,非类型模板参数不能具有类类型。甚至在C ++ 20中,这也会仍然格式错误,因为要选择使用dyn作为非类型模板参数,您需要:

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

到那时,它将起作用。


我认为他的意思是:

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

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

答案 1 :(得分: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;