为什么 auto_ptr 不支持 op->*()
auto_ptr(以及shared_ptr)尝试使它们的使用尽可能透明;也就是说,理想情况下,您不应该能够区分您使用的是 auto_ptr 还是真正的对象指针。考虑一下:
class MyClass
{
public:
void foo() { }
};
MyClass* p = new MyClass;
auto_ptr<MyClass> ap(new MyClassp);
p->foo(); // No notational difference in using real
ap->foo(); // pointers and auto_ptrs
当您尝试通过指向成员的指针调用成员函数时,存在差异,因为 auto_ptr 显然没有实现 op->*():
void (MyClass::*memfun)() = &MyClass::foo;
(p->*memfun)(); // OK
(ap->*memfun)(); // Error op->*() missing
(ap.get()->*memfun)(); // OK
为什么不支持 op->*( )在 auto_ptr 中以及如何实现它(我已经尝试了一段时间,但最终放弃了)。
auto_ptr (shared_ptr as well) try to make their use as transparent as possible; that is, ideally, you should not be able to tell a difference whether you're using an auto_ptr or a real pointer to an object. Consider:
class MyClass
{
public:
void foo() { }
};
MyClass* p = new MyClass;
auto_ptr<MyClass> ap(new MyClassp);
p->foo(); // No notational difference in using real
ap->foo(); // pointers and auto_ptrs
When you try to invoke a member function through a pointer-to-member, there is a difference, as auto_ptr obviously doesn't implement op->*():
void (MyClass::*memfun)() = &MyClass::foo;
(p->*memfun)(); // OK
(ap->*memfun)(); // Error op->*() missing
(ap.get()->*memfun)(); // OK
Why is there no support for op->*() in auto_ptr and how would one implement it (I've experimented for some time, but ultimately gave up).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
正如路德指出的那样,实施起来并不简单——但它是可能的。
您必须
operator->*
的参数类型,operator()
,其签名与成员函数相同暂时忽略限定符,下面是它的基本外观(使用 C+ +0x 以避免手动重复):
但最后,当我们首先可以使用绑定成员指针的函子时,为什么还要麻烦呢。
虽然我不能确定这一点,但如果您结合
(*p).*m
)..由于所需的工作与此功能所带来的收益之间的比例不佳,它通常可能不会被实现。
As Luther points out its non-trivial to implement - but it is possible.
You have to
operator->*
can be deducedoperator()
with a signature equivalent to the member functionIgnoring qualifiers for the momement, here is how it could basically look (using C++0x to avoid manual repitition):
But in the end, why bother when we could just use functors that bind member pointers in the first place.
While i can't be sure about it, if you combine the knowledge that
(*p).*m
)... its probably usually not implemented due to a bad ratio of the work-needed to the gains resulting from this feature.
实现 ->* 需要解决完美转发问题:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1385.htm
运算符->* 必须返回一个具有相同值的可调用对象参数列表作为指向成员对象的指针,正确处理常量、易失性和引用类型。然后它必须使用特殊的魔力来处理默认参数。这是困难的、容易出错、无法解决的,并且会消耗太多的编译时间,而且由于指向成员的指针是 C++ 中相对不太受欢迎的功能,因此它们通常被排除在智能指针实现之外。
implementing ->* would require to solve the perfect forwarding problem:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1385.htm
operator->* would have to return a callable object with the same parameter list as the pointer-to-member object, correctly handling const-,volatileness and reference types. And then it would have to employ special magic powers to handle default parameters. This is difficult, error prone, unsolvable and eats too much compile time and since pointer-to-members are a comparably marginally popular feature of C++, they are generally left out of smart pointer implementations.
我可能是错的,但我认为没有办法为指向成员函数的指针重载
operator->*
。这是因为p->*memfun
虽然作为将其视为可调用对象的表达式的一部分有效,但其本身并不是有效的表达式,并且没有类型。因此,操作符没有返回有效的类型。以下内容适用于指向成员的指针,但尝试将其用于指向成员函数的指针会出现错误,“无效使用非静态成员函数”,对于 GCC,以及内部编译器错误MSVC。
编辑:正如 Georg 的回答指出的那样,您可以使用 boost::bind 或类似的方法为成员函数创建一组重载,最多可达固定的最大参数数量,但仍然无法重载所有可能的成员函数的运算符。
I may be wrong, but I think there's no way to overload
operator->*
for a pointer-to-member-function. This is becausep->*memfun
, while valid as part of an expression that treats it as a callable object, isn't a valid expression in its own right, and doesn't have a type. There is therefore no valid type for the operator to return.The following will work for a pointer-to-member, but trying to use it for a pointer-to-member-function gives an error, "invalid use of non-static member function", with GCC, and an internal compiler error with MSVC.
EDIT: as Georg's answer points out, you can use
boost::bind
or similar to create a set of overloads for member functions up to a fixed maximum number of arguments, but there's still no way to overload the operator for all possible member functions.