In this video at 27:35 Bryce Lelbach gives the following example:
template<auto... Dims>
struct dimensions {};
struct dynamic_extent {};
constexpr dynamic_extent dyn = {};
dimensions<64, dyn, 32> d;
This code does not compile. GCC complains:
<source>:8:27: error: 'struct dynamic_extent' is not a valid type for a template non-type parameter
dimensions<64, dyn, 32> d;
^
Clang complains:
<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>
^
Is his example simply wrong (that's strange because he refers to a library where this idea is used) or I do not get something?
Yes, his example is wrong.
Non-type template parameters cannot have class type until P0732, which is a C++20 feature. And even in C++20, this would still be ill-formed because in order to opt-in to use dyn
as a non-type template parameter, you need:
struct dynamic_extent {
auto operator<=>(dynamic_extent ) = default;
};
At that point, it'll work.
I assume what he meant was:
dimensions<64, &dyn, 32> d;
// ^^^^
Passing that pointer is fine - pointers are acceptable non-type template parameters in C++17 (and way earlier), as long as they meet some other requirements - which dyn
does.
That example is wrong. This does not work in C++17. Non-type template parameters must be one of:
std::nullptr_t
- integral type
- lvalue reference type (to object or to function)
- pointer type (to object or to function)
- pointer to member type (to member object or to member function)
- enumeration type
Arbitrary class types are not in this list.
Note that it would work to use an enum as the tag type:
template<auto... Dims>
struct dimensions {};
enum class dynamic_extent {};
constexpr dynamic_extent dyn = {};
dimensions<64, dyn, 32> d;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With