【发布时间】:2014-09-22 13:09:53
【问题描述】:
我发现 this paper 实现了一个 C++ 代理包装类,它允许通过重载 operator-> 在每个方法调用之前和之后执行代码。
在第 11 节,技术中提到可以将包装器类链接到彼此中,例如
#include <iostream>
using namespace std;
template<class T, class Pref, class Suf> class Wrap;
template<class T, class Suf>
class Call_proxy {
T* p;
mutable bool own;
Suf suffix;
Call_proxy(T* pp, Suf su) :p(pp) , own(true) , suffix(su) { } // restrict creation
Call_proxy& operator=(const Call_proxy&) ; // prevent assignment
public:
template<class U, class P, class S> friend class Wrap;
Call_proxy(const Call_proxy& a) : p(a.p) , own(true) , suffix(a.suffix) { a.own=false; }
~Call_proxy() { if (own) suffix() ; }
T* operator->() const{ return p;} // error: ‘struct Shared<X>’ has no member named ‘g’
//T& operator->() const{ return *p;} // error: result of ‘operator->()’ yields non-pointer result
};
template<class T, class Pref, class Suf>
class Wrap {
T& p;
Pref prefix;
Suf suffix;
public:
Wrap(T& x, Pref pr, Suf su) :p(x) , prefix(pr) , suffix(su) { }
Call_proxy<T,Suf> operator->() const{
prefix() ;
return Call_proxy<T,Suf>(&p,suffix);
}
};
void prefix() { cout << "prefix "; }
void suffix() { cout << " suffix\n"; }
struct Pref { void operator()() const{ cout<< " Pref "; } };
struct Suf { void operator()() const{ cout<< " Suf "; } };
template<class T> struct Shared : public Wrap<T,Pref, Suf> {
Shared(T& obj) : Wrap<T,Pref, Suf>(obj,Pref() , Suf()) { }
};
template<class T> struct Tracer : public Wrap<T,void(*)() ,void(*)()> {
Tracer(T& x) : Wrap<T,void(*)() ,void(*)()>(x,::prefix,::suffix) { }
};
class X {
public:
void g() const{ cout << "g()"; }
};
int main() {// test program
X x;
Shared<X> xx(x) ;
Tracer<Shared<X>> xxx(xx);
xx->g();
xxx->g();
return 0;
}
但这会失败并出现错误error: ‘struct Shared<X>’ has no member named ‘g’。
我阅读了operator-> 重载并理解了问题(Call_proxy 返回一个指针,它不会传播重载,如 here 所述)。
我通过返回引用而不是指针尝试了一些替代方案,但最后我遇到了上面提到的问题,或者operator->被引用类型(error: result of ‘operator->()’ yields non-pointer result)调用的问题。
有没有办法做到这一点?正如论文中提到的,我认为应该是可能的。
编辑:两个错误的代码版本。
-
http://ideone.com/ff9UyN (
error: ‘struct Shared<X>’ has no member named ‘g’. 我读到了operator->) -
http://ideone.com/CV93qX (
error: result of ‘operator->()’ yields non-pointer result)
两个版本相同,只是第 17 行或第 18 行被注释掉了。
【问题讨论】:
-
请发布匹配的代码/错误,什么成员
g? -
@PaulEvans 我添加了 X、Tracer 和 Shared 的实现。 Wrap 和 Call_proxy 很长,从论文中 1:1 复制。但如果有帮助,我可以将它们添加到问题中?
-
你对这个问题的指导是here
-
我尽量减少
标签: c++