C++11:如何对函数进行别名
C++11: How to alias a function?
如果我在名称空间栏中有一个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+,经过优化
请参阅这些编译器生成的程序集。
类是类型,因此它们可以与typedef
和using
别名(在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();
}
相关文章:
- 使用定义函数模板别名
- 如何同时别名和实例化模板函数?
- 通过类型别名从构造函数转发模板推导
- typedef 别名的析构函数
- 函数的返回值类型是别名 ***或 *** 布尔值
- std::shared_ptr 使用别名构造函数,是否可以检索初始指针值?
- 使用其他模板类型参数作为要在函数签名中使用的类型别名声明
- 在模板派生类中继承具有类型别名的构造函数
- 模板类函数指针类型别名
- 使用函数数据类型键入别名和别名模板
- 是否可以为模板类的模板函数成员设置别名?
- 类方法和全局函数中的别名
- 别名一个模板函数,该功能没有参数可更简洁
- MSVC:带函数的"error C2244: unable to match function definition to an existing declaration"是指专用模板类的类型别名
- 为 OpenMP 函数创建别名 ||部分禁用 openMP
- Cython 创建 C 函数别名
- C++最佳实践 - 函数类型别名 std::function<T> 或 T
- 使用使用成员类型别名的构造函数来推论类模板参数
- 如何自己为我自己的shared_ptr实现实现别名构造函数
- 具有已知类型的别名函数模板