C++11:如何对函数进行别名

C++11: How to alias a function?

本文关键字:别名 函数 C++11      更新时间:2023-10-16

如果我在名称空间栏中有一个Foo类:

namespace bar
{
    class Foo { ... }
};

然后我可以:

using Baz = bar::Foo;

现在,它就像我在我的名称空间中定义了一个名为Baz的类。

是否可以对函数执行同样的操作?

namespace bar
{
    void f();
}

然后:

using g = bar::f; // error: ‘f’ in namespace ‘bar’ does not name a type

做这件事最干净的方法是什么?

该解决方案还应适用于模板函数。

定义:如果某个实体B是A的别名,则如果源代码中A的任何或所有用法(当然不是声明或定义)被B替换,则(剥离的)生成的代码保持不变。例如,typedef A B是一个别名。#define B A是一个别名(至少)。T& B = A不是别名,B可以有效地实现为间接指针,其中"未别名"的A可以使用"即时语义"。

您可以使用完美转发来定义函数别名(需要一些工作):

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

即使f重载和/或函数模板,此解决方案也适用。

constexpr函数指针可以用作函数别名。

namespace bar
{
    int f();
}
constexpr auto g = bar::f;

使用g很可能直接使用bar::f(但语言不能保证)。具体来说,这取决于编译器版本和优化级别。

特别是以下情况:

  • GCC 4.7.1+,未经优化
  • Clang 3.1+,无需优化
  • MSVC 19.14+,经过优化

请参阅这些编译器生成的程序集。

类是类型,因此它们可以与typedefusing别名(在C++11中)。

函数更像对象,因此没有别名机制。最多可以使用函数指针或函数引用:

void (*g)() = &bar::f;
void (&h)() = bar::f;
g();
h();

同样,也没有对变量进行混叠的机制(缺少直通指针或引用)。

可以在不更改名称的情况下将函数引入不同的作用域。这意味着您可以使用不同的限定名称对函数进行别名:

namespace bar {
  void f();
}
namespace baz {
  using bar::f;
}
void foo() {
  baz::f();
}

绝对:

#include <iostream>
namespace Bar
{
   void test()
   {
      std::cout << "Testn";
   }

   template<typename T>
   void test2(T const& a)
   {
      std::cout << "Test: " << a << std::endl;
   }
}
void (&alias)()        = Bar::test;
void (&a2)(int const&) = Bar::test2<int>;
int main()
{
    Bar::test();
    alias();
    a2(3);
}

尝试:

> g++ a.cpp
> ./a.out
Test
Test
Test: 3
>

引用是对现有对象的别名
我刚刚创建了一个对函数的引用。引用的使用方式与原始对象完全相同。

它不是标准的C++,但大多数编译器都提供了一种实现这一点的方法。有了GCC,你可以做到这一点:

void f () __attribute__ ((weak, alias ("__f")));

这创建了符号CCD_ 10作为CCD_。使用VC++,你可以用这种方式做同样的事情:

#pragma comment(linker, "/export:f=__f")

您可以使用好的旧宏

namespace bar
{
    void f();
}
#define f bar::f
int main()
{
    f();
}