'Why do C++ template names behave like concepts in parameter lists
It seems that C++20 compilers allow me to use the name of a template type, without parameters, as a template parameter, provided class template argument deduction works. For example:
template<auto t> struct nttp {};
// Why does the next line work?
template<nttp t> struct is_nttp_helper {};
template<auto t> concept is_nttp = requires { is_nttp_helper<t>{}; };
static_assert(!is_nttp<5>);
static_assert(is_nttp<nttp<5>{}>);
I don't see this described in a not of documentation, so am trying to figure it out from the standard. Is the nttp t template argument what they are calling "a placeholder for a deduced class type ([dcl.type.class.deduct])."?
If so, I would love to have a more generic concept that lets me constrain with arbitrary templates. Unfortunately, the following only works with clang, not g++:
template<template<auto> typename Tmpl, Tmpl> struct is_generic_helper{};
template<auto t, template<auto> typename Tmpl> concept is_generic =
requires { is_generic_helper<Tmpl, t>{}; };
// works with clang 13.0.1, not gcc 12.1.0:
static_assert(!is_generic<5, nttp>);
static_assert(is_generic<nttp<5>{}, nttp>); // works with both
My next question is which compiler is right here? Should the first static_assert be accepted or not?
My final question is whether there's any way to take advantage of this feature, other than as a template parameter, without needing to introduce helper types. For example, it would be nice to be able to introduce an easy constraint that takes the logical or of two template types, or negates a type.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
