在函数定义之外提升using语句

时间:2014-09-22 17:42:31

标签: c++ templates typedef using

以下是有效的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;
}

1 个答案:

答案 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;
};