【问题标题】:Determining return type of "generic function"确定“泛型函数”的返回类型
【发布时间】:2012-08-31 16:03:23
【问题描述】:

假设,我想开发一个通用库,它应该可以用于类似数字的类型,包括双精度类型和用户定义类型。我现在面临的问题是我不知道如何编写函数模板的返回类型,就像这样:

template<class T>
auto transmogrify(T x)
-> ???
{
    using std::abs;
    return abs(x)+2.0;
}

using 声明使此函数模板的主体适用于原始类型,因为它们没有关联的命名空间(因此,没有 ADL)。但是我希望 transmogrify 使用专门的 abs 函数,以防用户定义类型的作者提供他自己的 abs 函数。我不能简单地使用

-> decltype( abs(x)+2.0 )

因为这不适用于双打,因为 std::abs 不在范围内(据我所知)。但是写

-> decltype( std::abs(x)+2.0 )

将禁用 ADL。但禁用 ADL 不是一种选择。此外,专门的 abs 函数返回的值可能不是 T 类型,而是其他类型。

关于如何解决返回类型问题的任何想法,同时 (a) 保留 ADL 和 (b) 对于不提供专用 abs 的类型使用某些默认函数(如本例中的 std::abs)。

【问题讨论】:

  • #define ab using std::abs; your_template_fn #undef ab 不知道这是不是个好选择
  • @Mr.Anubis 以及如何使用此定义确定函数的返回类型?
  • 我猜-&gt; decltype( abs(x)+2.0 )
  • 就在函数def之前,我猜也使用它?顺便说一句,你的眼睛怎么了? :P
  • A similar problem 可以类似解决。

标签: c++ c++11 generic-programming decltype argument-dependent-lookup


【解决方案1】:

使用单独的命名空间,您可以在其中放置 using 子句。这可以防止命名空间污染,因为 using 子句仅适用于该命名空间。我建议将其命名为独特的名称,以免您不小心将其传播开来。

namespace transmog_detail
{
   using std::abs;

   template<class T>
   auto transmogrify(T x) -> decltype(abs(x) + 2.0)
   {
      return abs(x) + 2.0;
   }
}

// Then pull it into the current namespace, as recommended by @LucDanton.
using transmog_detail::transmogrify;

// Or if there is a reason, you can forward. 
// template<class T>
// auto transmogrify(T x)
// -> decltype(transmog_detail::transmogrify(x))
// {
//    return transmog_detail::transmogrify(x);
// }

【讨论】:

  • 非常聪明!未命名的命名空间可能会也可能不会使这个更干净。不确定。
  • @MooingDuck:可能会,也可能不会。如果您使用任何其他未命名的命名空间,它们也会有 using 子句,这可能是不可取的。
【解决方案2】:

上面的答案很好,但我能想到的最简单的方法是使用 typeinfo 标头。它专门用于确定对象的类型和构造函数。

请看这里:http://www.cplusplus.com/reference/std/typeinfo/type_info/

【讨论】:

  • -1 一点用都没有——type_info 是关于运行时类型识别,而声明需要静态确定的类型。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-06
相关资源
最近更新 更多