亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

C ++靜態多態性(CRTP)并使用派生類中的typedef

C ++靜態多態性(CRTP)并使用派生類中的typedef

C++
Helenr 2019-09-21 15:20:10
我閱讀了Wikipedia上有關C ++中反復出現的模板模式的信息,該模板模式用于執行靜態(閱讀:編譯時)多態性。我想對其進行概括,以便可以根據派生類型更改函數的返回類型。(這似乎應該可行,因為基本類型從template參數知道派生類型)。不幸的是,以下代碼無法使用MSVC 2010進行編譯(我現在無法輕松訪問gcc,因此我還沒有嘗試過)。有人知道為什么嗎?template <typename derived_t>class base {public:    typedef typename derived_t::value_type value_type;    value_type foo() {        return static_cast<derived_t*>(this)->foo();    }};template <typename T>class derived : public base<derived<T> > {public:    typedef T value_type;    value_type foo() {        return T(); //return some T object (assumes T is default constructable)    }};int main() {    derived<int> a;}順便說一句,我有一個使用額外模板參數的解決方法,但是我不喜歡它-當在繼承鏈中傳遞許多類型時,它將變得非常冗長。template <typename derived_t, typename value_type>class base { ... };template <typename T>class derived : public base<derived<T>,T> { ... };編輯:MSVC 2010在這種情況下給出的錯誤消息是 error C2039: 'value_type' : is not a member of 'derived<T>'g ++ 4.1.2(通過codepad.org)說error: no type named 'value_type' in 'class derived<int>'
查看完整描述

3 回答

?
catspeake

TA貢獻1111條經驗 獲得超0個贊

derivedbase在基類列表中將其用作模板參數時,它是不完整的。


常見的解決方法是使用特征類模板。這是您的示例,特征化。這顯示了如何通過特征使用派生類中的類型和函數。


// Declare a base_traits traits class template:

template <typename derived_t> 

struct base_traits;


// Define the base class that uses the traits:

template <typename derived_t> 

struct base { 

    typedef typename base_traits<derived_t>::value_type value_type;

    value_type base_foo() {

        return base_traits<derived_t>::call_foo(static_cast<derived_t*>(this));

    }

};


// Define the derived class; it can use the traits too:

template <typename T>

struct derived : base<derived<T> > { 

    typedef typename base_traits<derived>::value_type value_type;


    value_type derived_foo() { 

        return value_type(); 

    }

};


// Declare and define a base_traits specialization for derived:

template <typename T> 

struct base_traits<derived<T> > {

    typedef T value_type;


    static value_type call_foo(derived<T>* x) { 

        return x->derived_foo(); 

    }

};

您只需要專門base_traits用于模板參數derived_t的任何類型,base并確保每個專門化都能提供所需的所有成員base。


查看完整回答
反對 回復 2019-09-21
?
海綿寶寶撒

TA貢獻1809條經驗 獲得超8個贊

使用特征的一個小缺點是您必須為每個派生類聲明一個。您可以像這樣編寫一個不太冗長和繁瑣的解決方法:


template <template <typename> class Derived, typename T>

class base {

public:

    typedef T value_type;

    value_type foo() {

        return static_cast<Derived<T>*>(this)->foo();

    }

};


template <typename T>

class Derived : public base<Derived, T> {

public:

    typedef T value_type;

    value_type foo() {

        return T(); //return some T object (assumes T is default constructable)

    }

};


int main() {

    Derived<int> a;

}


查看完整回答
反對 回復 2019-09-21
?
慕斯王

TA貢獻1864條經驗 獲得超2個贊

在C ++ 14中,您可以刪除typedef和使用函數auto返回類型推導:


template <typename derived_t>

class base {

public:

    auto foo() {

        return static_cast<derived_t*>(this)->foo();

    }

};

之所以可行,是因為將歸還類型的推導base::foo延遲到derived_t完成為止。


查看完整回答
反對 回復 2019-09-21
  • 3 回答
  • 0 關注
  • 689 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號