2010-03-23 116 views
3

我有一個模板的問題,不知道有沒有可能的方式來實現我想做的事。這是我的問題。模板類型名稱問題

template <typename T> 
class A 
{ 
public: 

    typedef T*    pointer; 
    typedef const pointer const_pointer; 

    A() 
    {} 

    template <typename D> 
    A(const D& d) 
    { 
     // how can I store the D type 
     // so I can refer it later on 
     // outside of this function 
    } 
}; 

確定這裏是什麼,我想做一個更完整的代碼(它可能不是編譯)

class C 
{ 
public: 
    virtual ~C(){} 

    virtual void* get_d() = 0; 
private: 

}; 

template <typename T, typename D> 
class Cimpl : public C 
{ 
public: 
    Cimpl() 
    :t() 
    ,d() 
    {} 

    Cimpl(const T& t, const D& d) 
    :t(t) 
    ,(d) 
    {} 

    void* get_d() 
    { 
     return &reinterpret_cast<D&>(d); 
    } 

private: 
    T t; 
    D d; 
}; 

class B 
{ 
public: 
    B() 
    :p(0) 
    {} 

    template <typename T, typename D> 
    B(const T& t, const D& d) 
    :p(0) 
    {  
     try 
     { 
      p = new Cimpl<T, D>(t, d); 
     } 
     catch(...) 
     { 
      d(p); 
     } 
    } 

    void* get_d() 
    { 
     return (p != 0) ? p->get_d() : 0; 
    } 

    ~B() 
    { 
     delete p; 
    } 

private: 
    C* p; 
}; 

template <typename T> 
class A 
{ 
    struct example_d 
    { 
    }; 

public: 

    typedef T*    pointer; 
    typedef const pointer const_pointer; 

    A() 
    {} 

    template <typename D> 
    A(const T& t) 
    :b(t, example_d()) 
    { 
    } 

    template <typename D> 
    A(const T& t, const D& d) 
    :b(t, d) 
    { 
     // how can I store the D type 
     // so I can refer it later on 
     // outside of this function 
    } 

    // not type safe...as user can cast to any type 
    // if I can store the type user pass in previous 
    // then I can use it back 
    template <typename T> 
    T* get_d() 
    { 
     reinterpret_cast<T*>(b.get_d()); 
    } 

private: 
    B b; 
}; 

所以我可以使用類像

1)A<int> a(1);// with example_d as D 
2)A<int> b(1, another_d()) // with another_d 

我可以將模板更改爲2個參數,並將第2個類型的默認參數設置爲example_d。所以我可以達到1)但不是2)。正如我將要編寫這樣

A<int, another_d> b(1, another_d()); 

有點太長型...

+2

不能存儲類型本身,但也有變通方法。你想用D做什麼? – 2010-03-23 15:29:24

+2

參數'T'有什麼意義?這與問題有什麼關係? – Seb 2010-03-23 15:30:11

+0

我沒有澄清我實際上想做什麼。我想要一個類只需要一個模板參數。然後另一個模板類型提供參數構造函數。我可以在課程的其他部分使用D型,而不僅僅是類型D的通過 – stephenteh 2010-03-23 15:40:15

回答

3

不能存儲類型,你只能存儲對象。

(如果你想存儲傳遞給A的構造函數參數d,看type erasure。)

+1

這是一個很好的類型擦除鏈接。 – iain 2010-03-23 22:57:17

2

你不能‘拯救’這樣的類型名。你真正想做的是讓類型D成爲該類的模板參數之一,例如現在

template <typename T, typename D> 
class A 
{ 
public: 

    typedef T*    pointer; 
    typedef const pointer const_pointer; 

    A() 
    {} 

    A(const D& d) 
    { 
    } 
}; 

,如果你的問題是,你想與D型構造A<T>具有多態性與E型構造,而不必A<T,D>A<T,E>是兩種不同類型的A<T>,那麼該解決方案是一個基類:

template <typename T> 
class ABase 
{ 
public: 

    typedef T*    pointer; 
    typedef const pointer const_pointer; 

    ABase() 
    {} 

protected: 

    /* You might want to omit this constructor completely, 
    * depending on your use case */ 

    template<typename D> 
    ABase(const D& d) 
    { 
    } 
}; 

template <typename T, typename D> 
class A : public ABase<T> 
{ 
public: 

    A() 
    {} 

    A(const D& d) 
     : ABase(d) 
    { 
    } 
}; 
0

如果你想使用類型d A類的其他成員函數,可以使d類A的第二個模板參數

+1

其實我知道這一點,但我只需要一個模板參數。所以想知道有沒有辦法。謝謝 – stephenteh 2010-03-23 15:31:25

+0

你有什麼理由不能擁有兩個模板參數嗎?如果是這樣的話,你可以從另一個類Abase派生出A,它將D作爲它的模板參數。 – Dima 2010-03-23 15:34:35

+1

@stephenteh:你如何告訴我們你想要存儲'D'的? – sbi 2010-03-23 15:35:49

1

這看起來像你正試圖創建一個具有boost::any成員變量的模板類。你應該看看這是一個可能的方式。

基本上是一個boost::any可以接受任何類型的值。如果您稍後知道類型,則可以安全地檢索該類型。你將如何使用這方面的一個很好的例子是將不同的數據類型存儲在一個地圖,(你知道類型後,當您檢索它的名字的話)。

如果這不正是你正在尋找的內部使用一個巧妙的技巧來實現它,它可能會幫助你實現你想要做的。