Digamos que tengo una función de plantilla:
template <typename A, typename B>
A fancy_cast(B)
{
return {};
}
El uso previsto es algo así fancy_cast<int>(1.f)
.
Pero nada impide que el usuario especifique manualmente el segundo parámetro de plantilla: fancy_cast<int, int>(1.f)
lo que causaría problemas.
¿Cómo puedo evitar que typename B
se especifique y forzar que se deduzca?
Se me ocurrió esto:
// 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, pero es extremadamente engorroso. ¿Hay una mejor manera?
A
yB
? No veo por qué no lo haría.protected
,require_deduction...
no requiere estar vacío (al contrario deenable_if_t<sizeof...(Ts) == 0>
). No es porque no pueda construir algunos valores que la plantilla no sea válida. Del mismo modo,struct S{}; using member_ptr_t = void (S::*)();
es válido, incluso siS
no tiene miembros.member_ptr_t
se puede inicializar connullptr
, pero si no pudiera, diría que no se puede hacer un paquete de parámetros.