我正在写一个模板包装器,像这样

template<class T>
class Wrapper{
public:
    Wrapper(T data);
    ~Wrapper();

    void doSomeWrapperWork();

private:
    T data;
};

如果要访问包装的数据,显然可以添加一个getter函数,该函数返回对该数据的引用。但是我想知道是否有某种模板魔术可以直接调用基础包装数据的包装函数。换句话说,如果我有一个带有公共(public)函数TestObjectvoid foo()类,我希望能够以这种方式调用它:
Wrapper<TestObject> myWrapper;
myWrapper.foo();

代替:
myWrapper.getData().foo();

没有先验地知道存在这样的功能。这可能吗?

最佳答案

不完全是,直到C++得到反射(reflect),我们才能在没有大量样板宏的情况下轻松编写包装器类



您可以将包装器类的隐式转换添加到T:

template<class T>
class Wrapper{
public:
    Wrapper(T data_) : data(data_) {}

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

private:
    T data;
};

现在您的类可以转换为T,因此我们可以在T上调用一个方法,而只需做一些工作:

用法:
struct Foo
{
    constexpr int bar() const
    {
        return 42;
    }
};

int main()
{
    constexpr Foo f;
    Wrapper<Foo> my_wrapper(f);
    static_assert(static_cast<const Foo&>(my_wrapper).bar() == 42);
}

Demo

如果要避免自己进行强制转换,则可以编写一个自由函数来调用您的函数,以便隐式转换可以接管:
int call_bar(const Foo& f)
{
    return f.bar();
}

用法:
Foo f;
Wrapper<Foo> my_wrapper(f);
std::cout << call_bar(my_wrapper); // 42

Demo2

我有点喜欢这种方法,因为它所需要的只是为我们想要的每个包装函数添加一个自由函数,而不必手动进行大量转换。

关于c++ - 将函数调用转发给包装模板中的基础数据,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/60307430/

10-11 22:43
查看更多