初始引用成员使用crtp

时间:2014-06-12 08:22:01

标签: c++ crtp

有没有办法使用CRTP初始化引用?

我的目标是制作类似以下代码的内容

#include <iostream>

int gI = 1;

template <typename Derived>
struct A
{
    A()
    {
        static_cast<Derived*>(this)->InitRefs();
    }

    void InitInt(int & i) { i = gI; }
};

struct B : public A<B>
{
    B() : A<B>() {}

    void InitRefs()
    {
        InitInt(i);
    }

    int & i;
};

int main()
{
    B b;
    std::cout << b.i;
}

1 个答案:

答案 0 :(得分:3)

必须在 mem-initializer-list 中初始化参考成员,并且(与所有参考文献一样)无法重新安装。

如果希望基类模板提供引用成员初始值设定项,请考虑提供返回int左值引用的成员函数:

template <typename Derived>
struct A {
    int& InitInt() { return gI; }
};

struct B : public A<B> {
    B() : A<B>(), i(InitInt()) {}
    int & i;
};

否则,如果您致力于当前的设计,请考虑使用std::reference_wrapper<int>,其行为类似于有限的参考,并且可以重新设置:

template <typename Derived>
struct A {
    A() {}
    void InitInt(std::reference_wrapper<int> & i) { i = gI; }
};

struct B : public A<B> {
    B() : A<B>() { InitRefs(); }
    void InitRefs() { InitInt(i); }
    std::reference_wrapper<int> i;
};

请注意,您无法从基类构造函数中调用InitRefs,因为在输入构造函数体之前,派生类对象不存在。