C + + 11: 如何别名一个函数?

如果我在名称空间栏中有一个 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 可以使用“即时语义”。

57840 次浏览

Classes are types, so they can be aliased with typedef and using (in C++11).

Functions are much more like objects, so there's no mechanism to alias them. At best you could use function pointers or function references:

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


g();
h();

In the same vein, there's no mechanism for aliasing variables (short of through pointers or references).

You can define a function alias (with some work) using perfect forwarding:

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

This solution does apply even if f is overloaded and/or a function template.

Absolutely:

#include <iostream>


namespace Bar
{
void test()
{
std::cout << "Test\n";
}




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);
}

Try:

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

A reference is an alias to an existing object.
I just created a reference to a function. The reference can be used in exactly the same way as the original object.

It's not standard C++, but most compilers provide a way of doing this. With GCC you can do this:

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

This creates the symbol f as an alias for __f. With VC++ you do the same thing this way:

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

It's possible to introduce the function into a different scope without changing its name. That means that you can alias a function with a different qualified name:

namespace bar {
void f();
}


namespace baz {
using bar::f;
}


void foo() {
baz::f();
}

You can use good old macros

namespace bar
{
void f();
}


#define f bar::f


int main()
{
f();
}

The constexpr function pointer can be used as a function alias.

namespace bar
{
int f();
}


constexpr auto g = bar::f;

It is highly likely (but not guaranteed by the language) that using g uses bar::f directly. Specifically, this depends on compiler version and optimization level.

In particular, this is the case for:

  • GCC 4.7.1+, without optimization,
  • Clang 3.1+, without optimization,
  • MSVC 19.14+, with optimization.

See assembly generated by these compilers.