2014-06-12 128 views
1

有沒有辦法使用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; 
} 

回答

3

參考成員必須在MEM-初始化列表被初始化,並(像所有的引用)不能被重新插拔一下。

如果你想在基類模板提供參考成員初始值設定,可以考慮提供成員函數返回一個左值參考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,作爲DERI在輸入構造函數體之前,ved類對象不存在。