我最近发现C++中存在.*
运算符(和密切相关的->*
运算符)。(参见这个问题。)
一开始看起来很不错,但是我何时需要使用它呢?链接问题中的两个答案提供了一些虚构的示例,这些示例将受益于直接函数调用。
在直接函数调用不方便的情况下,可以使用函数对象,例如可能在std::sort
中使用的lambda函数。 这将消除一个间接级别,因此比使用.*
更有效率。
链接问题还提到了该示例的简化版本:
struct A {
int a;
int b;
};
void set_member(A& obj, int A::* ptr, int val){
obj.*ptr = val;
}
int main()
{
A obj;
set_member(obj, &A::b, 5);
set_member(obj, &A::a, 7);
// Both members of obj are now assigned
}
不过这样做相当简单(也许甚至更好的做法,因为它更加干净,而且不会不必要地局限于A
类成员),可以使用以下方法:
struct A {
int a;
int b;
};
void set_me(int& out, int val){
out = val;
}
int main()
{
A obj;
set_me(obj.b, 5);
set_me(obj.a, 7);
// Both members of obj are now assigned
}
总之,一个指向成员函数的指针可以被一个函数对象所取代,而一个指向成员变量的指针可以被该变量的直接引用或一个函数对象所取代。这样做可能还会由于少了一次间接寻址而提高代码的效率。
这个问题 只提供了我的结论成立的例子,因此它并没有回答我的问题。
除了在与使用.*
的遗留代码进行接口时(在这种情况下根本没有选择),我真正想使用.*
的情况是什么时候?
PropertyImpl
中添加了第三个模板参数,它是一个可调用对象,接受一个类型为Class
的单一参数,并返回对正确成员的引用。毕竟,你已经在使用模板了。通过这种方式,元组元素的类型已经封装了足够的信息来找到正确的成员,从而消除了存储指向成员的指针的需要。 - Bernard