如何访问包装模板对象的功能

时间:2013-10-28 06:56:55

标签: c++

我目前正在为现有的类编写包装器。在不更改任何直接使用现有类的客户端代码的情况下编写包装器的最佳方法是什么?

class A
{
public:
    void foo() {}
};

template<typename T>
class Wrapper
{
// ...other wrapper data/functionality...
private:
    T myObject;
};

main()
{
    Wrapper<A> wrappedA;
    wrappedA.foo();
}

编译在msvc中失败,错误为C2039:'foo':不是'Wrapper'的成员

在不更改main中的任何代码的情况下,使模板包装器类工作的最佳方法是什么?

  • 选择运算符。不能超载
  • 将强制转换操作符写入类型T没有帮助,因为编译器在进行选择之前不会尝试强制转换
  • 我们可以编写一个get函数来返回内部myObject成员,但是main中的客户端代码必须被重写。如果有大量现有代码直接使用myObject而没有我们试图编写的新包装类,那就不好了。

修改

  • 我想在myObject上编写一个包装类,而不必更改任何直接使用myObject的现有客户端代码
  • A :: foo()不能带入包装器,因为其他类型T可能没有T :: foo()

3 个答案:

答案 0 :(得分:3)

您需要通过A实例调用它:

wrappedA.myObject.foo();

你的包装器不是一个非常聪明的包装器,所以你需要知道它包含一个名为myObject的实例。你可以通过给它一个转换运算符来使它变得聪明:

template<typename T>
class Wrapper
{
public:
    T myObject;

    operator const T& () const { return myObject; }
    operator T& () { return myObject; }
};

这样您就可以在需要A的地方使用它:

void bar(const A& a) { a.foo(); } // (make A::foo() a const method)

Wrapper<A> a;
bar(a);  // OK 

答案 1 :(得分:2)

提供运营商 - &gt;如果必须使用 - >返回指向包装类的指针访问方法不是问题:

template
class Wrapper
{
public:
  T* operator->() { return &myObject; }
  T const* operator->() const { return &myObject; }
...
};

但是如果你真的想用dot来访问方法,那么可能从T派生Wrapper? (但是你的课程根本不是一个包装工具:D)

答案 2 :(得分:2)

使用wrappedA.myObject.foo();代替wrappedA.foo();