Date: Tue, 21 Oct 2025 14:27:04 +0000 (UTC)
Proposal: template parameter values determined from Idiomatic use of decltype
Specifically, decltype(arg), arg being the name of a formal function parameter, is the decltype of the actual parameter when
the template function is called. The parameter value is specified after the parameter name, in braces, like the initialization
syntax. For example:
struct A
{
A(int);
…
};
template <typename T>
struct Rev
{
using type = T;
};
template <>
struct Rev<int>
{
using type = A;
};
template <typename T{Rev<decltype(v)>::type} , int Arg_size{sizeof(decltype(v))}>
void f(T v)
{
…
}
(I'm assuming there’s no need to require typename before Rev<decltype(v)>::type .)
So for this call to f():
f(5);
The implied value for T would be A.
The first use of this that I have in mind is for optimal forwarding of input parameters to template functions, something like this:
template <typename T>
struct Pass_by_value
{
static const bool value{(sizeof(T) <= sizeof(void *)) and std::is_trivially_copyable_v<T>};
}
template <typename T, bool = Pass_by_value<T>::value>
struct Input_arg
{
using type = const T &;
};
template <typename T>
struct Input_arg<T, true>
{
using type = T;
};
template <typename T{Input_arg<decltype(v)>::type}>
void g(T v)
{
…
}
A compilation error would result if the actual parameter could not implicitly convert to its determined type.
I think this could also be used to determine class template arguments from constructor calls.
Specifically, decltype(arg), arg being the name of a formal function parameter, is the decltype of the actual parameter when
the template function is called. The parameter value is specified after the parameter name, in braces, like the initialization
syntax. For example:
struct A
{
A(int);
…
};
template <typename T>
struct Rev
{
using type = T;
};
template <>
struct Rev<int>
{
using type = A;
};
template <typename T{Rev<decltype(v)>::type} , int Arg_size{sizeof(decltype(v))}>
void f(T v)
{
…
}
(I'm assuming there’s no need to require typename before Rev<decltype(v)>::type .)
So for this call to f():
f(5);
The implied value for T would be A.
The first use of this that I have in mind is for optimal forwarding of input parameters to template functions, something like this:
template <typename T>
struct Pass_by_value
{
static const bool value{(sizeof(T) <= sizeof(void *)) and std::is_trivially_copyable_v<T>};
}
template <typename T, bool = Pass_by_value<T>::value>
struct Input_arg
{
using type = const T &;
};
template <typename T>
struct Input_arg<T, true>
{
using type = T;
};
template <typename T{Input_arg<decltype(v)>::type}>
void g(T v)
{
…
}
A compilation error would result if the actual parameter could not implicitly convert to its determined type.
I think this could also be used to determine class template arguments from constructor calls.
Received on 2025-10-21 14:27:10
