That’s basically std::integral_constant which has an implicit conversion to its value_typ (the operator value_type member function):
auto a = std::integral_constant<int, 3>{};
int b = a;
assert(b == 3);
The lifting @comex suggests goes, however, in the opposite direction (from value_type to integral_constant):
int a = 3;
std::integral_constant b = 3; // ERROR
static_assert(std::is_same<decltype(b), std::integral_constant<int, 3>>{});
This currently does not work in C++, but it might work in the future. C++17 added a feature called “class template argument deduction” (CTAD) that deduces class template arguments from constructor parameters. Without CTAD one has to specify class template arguments when constructing objects:
std::vector<int> a{10};
but with CTAD one does not (they are deduced from the constructor arguments), that is, the following is valid C++17:
std::vector a{10}; // T deduced to `int`
Currently, CTAD already works for non-type template parameters like int:
std::integral_constant<int, 3> a{};
std::integral_constant b{a}; // deduced to <int, 3>
but what it cannot currently do is deduce a template parameter from a function’s argument value, e.g.,
std::integral_constant c{3}; // error
It is unclear at this point whether that will ever be supported, but @ubsan mentioned on Discord that the authors of the constexpr! proposal might pursue constexpr function arguments in the future - it might be possible to extend the language such that CTAD interacts with those but I don’t know whether this is already being explored right now.
@comex
To be honest, this approach feels kind of ‘C+±ish’ to me (even though C++ doesn’t actually have an equivalent!), and I don’t know whether it’s ideal.
I get the same feeling, but it is an interesting alternative worth exploring.