c++ - 使用 crtp 初始化引用成员

标签 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;
}

最佳答案

引用成员必须在 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来自基类构造函数,因为派生类对象在进入其构造函数体之前不存在。

关于c++ - 使用 crtp 初始化引用成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24179615/

相关文章:

c++ - 从头文件中的命名空间访问类型

c++ - glGenQueries 总是返回非查询对象,glBeginQuery 返回错误

c++ - 从 C++ std::vector 中删除第 i 个项目

c++ - 使用依赖于类型的模板名称的声明

c++ - 我怎样才能在 C++ 中循环对

c++ - Cent OS 6.3 上 usleep 的 CPU 使用率高

c++ - 我可以以某种方式公开模板模板参数吗?

c++ - 继承通用成员函数

C++:使用 CRTP,派生类中定义的类在基类中不可访问

c++ - 为什么在通过 CRTP 访问派生类中的 typedef 时出错?