我想减少引用函数所需的语法量,并且想知道是否有办法执行以下操作:
(不可编译)
using pushToLastUsed = mSomeLongStackFIFOObject.push_back;
// or
auto pushToLastUsed = mSomeLongStackFIFOObject.push_back;
然后我可以这样说:
pushToLastUsed(10);
而不是:
mSomeLongStackFIFOObject.push_back(10);
当然,我可以制作一个宏,例如:
#define pushToLastUsed mSomeLongStackFIFOObject.push_back
// some code using it here
#undef pushToLastUsed
但我宁愿不使用宏。
一种解决方案可能是使用 lambda 表达式将函数调用捕获到可调用对象中:
#include <vector>
void foo(std::vector<int> & bar)
{
auto pushToLastUsed = [&bar](int index) {
bar.push_back(index);
};
pushToLastUsed(10);
}
尽管在我看来,即使您用很长的标识符替换bar
,这样做也没有什么好处。
我的第一个想法是另一个答案。在第二次阅读您的问题时,我了解到主要是您要避免重复的对象长名称。隐藏对标准函数的调用应小心,因为它的主要作用是混淆代码。每个人都知道push_back
做什么,但即使是你也可能忘记pushToLastUse
到底是做什么的。另一种选择是仅使用较短名称为mSomeLongStackFIFOObject
设置别名,如
auto& short_name = mSomeLongStackFIFIObject;
short_name.push_back(10);
当你在写mSomeLongStackFIFOObject.push_back(10);
时,你实际上是在调用SomeLongStackFIFOClass::push_back(&mSomeLongStackFIFOObject, 10);
一种选择是执行以下操作:
auto& m= mSomeLongStackFIFOObject;
然后:
m.push_back(10);
它将缩短它,并且仍然允许您使用您喜欢的任何变量。
如果变量是全局变量,则始终可以执行以下操作:
static inline void pushBack(int n) { mSomeLongStackFIFOObject.push_back(n); }
如果你试图缩短访问时间,我可以猜到你不止一次地使用该变量;那么尝试将所有访问放在属于该类的函数中可能是有意义的。
通过将对象mSomeLongStackFIFOObject
绑定到成员函数push_back
并使用占位符作为其参数来实现所需的行为。这至少需要一个 C++11 编译器。
请考虑以下示例:
#include <functional>
#include <iostream>
struct A {
void push_back(const int& n) { std::cout << "push_back(" << n << ")n"; }
};
int main() {
A mSomeLongStackFIFOObject;
std::function<void(const int&)> pushToLastUsed = std::bind(
&A::push_back,
&mSomeLongStackFIFOObject,
std::placeholders::_1
);
pushToLastUsed(10); // push_back(10)
}
关于此的一些注意事项:
- 正如 Mirko 已经正确提到的,调用非静态成员函数与调用静态成员函数基本相同,
this
作为隐式第一个参数。将struct A
实例绑定为第一个参数利用了这一事实。 - 使用
auto
的类型推断确实适用于没有任何参数的成员函数,但在上述情况下则不然。 - 如果非静态成员函数重载(例如
std::vector<T>::push_back
),您必须显式声明函数模板std::bind
的模板参数。请参阅使用 std::tr1::bind with std::vector::p ush_back 或者VS2010是否存在提升::绑定问题?了解更多信息。