如何将"using"用于函数?

How to use "using" for a function?

本文关键字:函数 用于 using      更新时间:2023-10-16

如何使用"using"作为函数?例如

class A;
void f(int);
struct B
{
   using BA = A;
   using Bf = f; ???
};

你可以做

struct B
{
   using BA = A;
   constexpr static auto Bf = f;
}

这样,您就不必担心指定类型,这可能会很烦人。

您不想声明非静态变量,否则对象的每个副本都将携带一个函数指针。您也不希望它是可变的,因为这样您就可以重新分配它。你也不希望在运行时确定它,因为这样编译器将不得不在给定的上下文中向自己证明对Bf的调用实际上是在调用f,否则支付函数间接成本。constexpr处理最后两点。

如果f只是一个函数,则可以添加一个成员函数指针:

void (*Bf)(int) = f;

或者只是将其包装在一个函数中:

void Bf(int i) { f(i); }

不过可能更喜欢后者,因为它避免了向B添加额外的成员。

<小时 />

如果f是函数模板,则不能只是别名,而是需要转发到它:

template <class... Args>
auto Bf(Args&&... args)
    -> decltype(::f(std::forward<Args>(args)...))
    noexcept(noexcept(::f(std::forward<Args>(args...))))
{
    return ::f(std::forward<Args>(args)...);
}

这是...是的。

Nir Friedman的答案很好,但如果f过载,它就不起作用了。

在 C++14 中,您可以使用通用 lambda 对此有一个解决方案:

struct B {
  using BA = A;
  static constexpr auto BF = [](auto&&... args) {
    return f(std::forward<decltype(args)>(args)...);
  };
};

如果这看起来有点复杂,那只是因为std::forward的啰嗦。我将不std::forward地展示它,以使其更易于掌握(但不使用它,因为如果f引用类型作为参数,它会失败):

struct B {
  using BA = A;
  static constexpr auto BF = [](auto... args) { return f(args...); };
};
区别在于

A只是一个类型,而f是一个实际的函数。如果要使用 usingBf定义为f的类型,请使用:

using Bf = decltype(f);