【问题标题】:Lifting a using statement outside of function definition在函数定义之外提升 using 语句
【发布时间】:2014-09-22 17:42:30
【问题描述】:

以下是有效的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&lt;BAR, BAZ&gt; 实际上可能是一个相当长的标识符,我希望以某种方式将 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;
}

【问题讨论】:

  • 您可以使用类型函数 (C++98) 或返回类型推导 (C++14)。您还可以在某些命名空间中隐藏这些 u​​sing 语句,在那里定义您的函数,并通过 decltype 使用 C++11 样式的返回类型“推论”在外部提供一个包装器。
  • "Foo 实际上可能是一个相当长的标识符",但您可以通过键入 BAR 和 BAZ 来使其更短(并且更易于理解)。
  • @dyp 好主意,但是命名空间外的函数包装器的参数是否也需要使用 Foo 声明?
  • 啊,我没有仔细检查你的例子。使用此技术无法轻松摆脱函数参数类型。类型函数仍然可以正常工作。
  • #define 和 #undef? ;)

标签: c++ templates typedef using


【解决方案1】:

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&lt;.....&gt;(或 C++14 之前的typename std::enable_if&lt;.....&gt;::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&amp;)而不是显式返回类型,并让编译器从返回值推导出它。

如果你想知道模板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;
};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-02-27
    • 2021-01-04
    • 1970-01-01
    • 2014-02-19
    • 2011-02-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多