在函数模板中,形参的类型是由一些trait类决定的,所以它们的类型可能会很长,比如
template<typename A>
void func(typename Traits<A>::some_type_x x1, typename Traits<A>::some_type_x x2);
有办法混叠这些类型吗?我目前的解决方案是在模板参数
中引入另一个类型名。template<typename A, typename X = typename Traits<A>::some_type_x>
void func(X x1, X x2);
但是这些可能会让函数调用者提供一些无效参数,所以我想知道是否有一个更优雅的解决方案来解决这个问题?
您可以像类型支持库那样声明helper类型。例如
template<class T>
using Traits_x = typename Traits<T>::some_type_x;
然后使用
template<typename A>
void func(Traits_x<A> x1, Traits_x<A> x2);
template <typename A, typename X = typename Traits<A>::some_type_x>
void func(X x1, X x2);
有两个问题:
- X现在是可演绎的(所以默认模板基本没用)。
- 正如你提到的,它可以被
func<A, int>(42, 51);
劫持
对于第一个问题,您可以使用std::type_identity_t
:
template <typename A, typename X = typename Traits<A>::some_type_x>
void func(std::type_identity_t<X> x1, std::type_identity_t<X> x2);
,对于第二个,您可以引入一个参数包,其中包含任何额外的参数:
template <typename A, typename..., typename X = typename Traits<A>::some_type_x>
void func(std::type_identity_t<X> x1, std::type_identity_t<X> x2);
但我不确定它是不是比原来的好……