以下是有效的c ++:
template <typename BAR, int BAZ>
Foo<BAR, BAZ> & operator -= ( Foo<BAR, BAZ> & left, Foo<BAR, BAZ> const right )
{
using reference = Foo<BAR, BAZ> &;
using const_value = Foo<BAR, BAZ> const;
...
return left;
}
但是Foo<BAR, BAZ>
实际上可能是一个非常长的标识符,我希望以某种方式将using语句应用于除了内容之外的函数定义,如果只是为了美学和清晰。基本上,是否有可能写出与以下类似的东西作为独立功能?
template <typename BAR, int BAZ>
... // using/typedef statements that define 'reference' and 'const_value',
... // but only defines them for this function
reference operator -= ( reference left, const_value right )
{
...
return left;
}
答案 0 :(得分:0)
SFINAE。
首先定义一个类型区分元函数(type -> bool)
template<class> struct is_Foo : std::false_type {};
template<class X, class Y> struct is_Foo<Foo<X,Y>> : std::true_type {};
然后将其与 std::enable_if_t<.....>
(或 C++14 之前的 typename std::enable_if<.....>::type
)一起使用
第一种方法是添加一个从 T 派生的虚拟模板参数。 成功时它变成无效,失败时 - SFINAE 使编译器跳过此重载。
template<class T, class = std::enable_if_t<is_Foo<T>::value>>
T& operator -= (T& src, const T& dst)
{
.....
return src;
}
第二种方法更方便,尝试导出结果类型。 如果成功,它应该正是我们必须返回的。
template<class T>
std::enable_if_t<is_Foo<T>::value, T&> operator -= (T& src, const T& dst)
{
.....
return src;
}
第一种方式的好处是写auto
(或auto&
)而不是显式返回类型,让编译器从返回值中推导出来。
如果你想知道模板 Foo 的参数,只需扩展元函数即可。
template<class> struct traits_of_Foo; // undefined for non-Foo types
template<class X, class Y> struct traits_of_Foo<Foo<X,Y>>
{
using Param1 = X;
using Param2 = Y;
};