Digamos que eu tenho uma função de modelo:
template <typename A, typename B>
A fancy_cast(B)
{
return {};
}
O uso pretendido é algo parecido fancy_cast<int>(1.f)
.
Mas nada impede que o usuário especifique o segundo parâmetro do modelo manualmente:, o fancy_cast<int, int>(1.f)
que causaria problemas.
Como impedir que typename B
seja especificado e forçar a dedução?
Eu vim com isso:
// Using this wrapper prevents the code from being
// ill-formed NDR due to [temp.res]/8.3
template <auto V> inline constexpr auto constant_value = V;
template <
typename A,
typename ...Dummy,
typename B,
typename = std::enable_if_t<constant_value<sizeof...(Dummy)> == 0>
>
A fancy_cast(B)
{
return {};
}
Parece funcionar, mas é extremamente complicado. Existe uma maneira melhor?
A
eB
? Não vejo por que não.protected
,require_deduction...
não precisa estar vazio (ao contrário deenable_if_t<sizeof...(Ts) == 0>
). Não é porque você não pode construir alguns valores que o modelo é inválido. Da mesma forma,struct S{}; using member_ptr_t = void (S::*)();
é válido, mesmo queS
não tenha membros.member_ptr_t
pode ser inicializado comnullptr
, mas se não pudesse, diria que você não pode criar um pacote de parâmetros com ele.