2014-02-28 24 views
0

我有需要傳遞給它的兩個獨立的模板類:如何將多個模板傳遞到一類

template <typename T> 
class AwesomeClass 
{ 
    TList *theList; 
    typename list <T>::iterator theiterator; 

    public: 
    template <typename TList> 
    AwesomeClass(TList &list) 
    { 
    theList = &list; 
    }; 
} 

正如你可能知道它本質上提供的包裝爲STL(我必須這樣做這條路)。理想情況下,我不希望通過在對象的聲明像這樣通過兩個模板:

typedef AwesomeClass<int, BaseClass<int> > BaseClassIteratorInt; 

以及與此寧願脫身:

typedef BaseClass<int> ListFromBaseClassInt; 
typedef AwesomeClass<int> BaseClassIteratorInt; 
BaseClassIteratorInt newInt(ListFromBaseClassInt) 

(這是上面的代碼的意思做)

不過,我不斷收到錯誤:

error C2143: syntax error : missing ';' before '*'

對於變量從TList *的thelist。

我需要爲ctor提供TList的類型,有沒有辦法做到這一點?

額外步驟:

好吧,我現在有格式的代碼:

template <typename Container> 
class AwesomeClass 
{ 
    public: 
    typedef typename std::common_type<Container> value_type; 

    bool firstUse; 

    Container *theList; 
    typename Container::iterator theIterator; 
    explicit AwesomeClass(Container &list):theList(&list) 
    { 
    }; 
} 

這是使用common_type繞過編譯器故障而其停止生產線

typedef typename Container::value_type value_type; 

編譯由於value_type不是全局名稱空間的一部分。

但我有一個編譯器錯誤的編譯器,編譯器聲稱它需要一個';'在它之前。

任何人都可以看到什麼是錯的?

+0

ListIterator是實際的名稱,我一般會嘗試更改類名稱等當我張貼在論壇上,錯過了! – Stefan

+0

我可以理解,如果名稱是專有的。但請保持一致。更不用提的是,在這種情況下,原始名稱是精心挑選的,因爲它可以自我記錄班級的工作。爲什麼讓我們難以理解您希望我們幫助您的代碼? – Angew

+0

就這樣我得到了這個直 - 你的類存儲一個指向任意列表類型的指針,並將迭代器存入'std :: list '?你可能想要更好地解釋你的目的,因爲這一眼看不出來。 – Angew

回答

0

它聽起來像你需要一個前向聲明TList:你使用if之前聲明它,所以編譯器不知道它。

+0

如果我爲TList添加前向聲明,我似乎在首次使用聲明該類型未定義時出現錯誤? – Stefan

0

您需要聲明TList作爲模板參數,然後才能在其他聲明中使用它。

template <typename TList, typename T> 
class AwesomeClass { 
    TList* theList; 

    /* ... */ 
}; 

而且你不需要申報第二個模板參數T,而不是得到的類型,像這樣:

using value_type = typename TList::value_type; 

其次,你不必使用模板扣在構造函數。

// template <typename TList> // Unnecessary if the template parameter is already declared 
AwesomeClass(TList& list) { 
    theList = &list; 
} 

第三,您已將分號放在ctor之後,而不是放在類作用域的末尾。

/* ... */ 

AwesomeClass(TList& list) { 
    theList = &list; 
    }; // Unnecessary to put semicolon after function definitions. 
} // Although, you need semicolon here. 

它看起來像你希望能夠創造AwesomeClass對象時,自動推斷類型的模板參數。但是,模板參數可以自動推算出而不是,只有函數模板可以做到這一點。

要完成模板參數的自動扣除,您可以創建一個函數,該函數返回帶有推導參數的AwesomeClass,例如,

template <typename TList> 
auto make_awesome(TList& list) -> AwesomeClass<TList, typename TList::value_type> { 
    return {list}; 
} 

編輯:

如果你想要的是一個存儲指向任何類型的std::list那麼所有你需要演繹的是元素類型的類。但是,你只能存儲指向容器的指針,而不是例如。一個指向std::vector的指針。

template <typename T> 
class AwesomeClass { 
public: 
    AwesomeClass(std::list<T>& c) { 
     c_ = &c; 
    } 
private: 
    std::list<T>* c_; 
    typename std::list<T>::iterator iter_; 
}; 

int main() { 
    typedef AwesomeClass<int> BaseClassIteratorInt; 
    BaseClassIteratorInt b{l}; 
} 
+0

但是,如果我添加TList作爲模板參數(如您所示),當嘗試使用聲明時出現錯誤:typedef AwesomeClass BaseClassIteratorInt; ,因爲參數太少。在函數聲明結尾處有一個分號,實際上並沒有什麼區別,儘管我已經刪除了它,因爲它不是有意的! – Stefan

+0

@Stefan如果類需要兩個模板參數,那麼您必須提供兩個參數。試試這個:'typedef AwesomeClass ,int> BaseClassIteratorInt;' – Snps

+0

這有效,但它已經是我現在所擁有的了。我要替換的庫僅在typedef中使用一個參數來聲明它們的類。如果可能,我希望界面相同。 – Stefan

0

隨着

template <typename T, typename TList> class AwesomeClass 
class AwesomeClass 
{ 
    TList *theList; 
    typename list<T>::iterator theiterator; 

public: 
    explicit AwesomeClass(TList &list) : theList(&list) {} 
}; 

你可以做什麼在建設推斷類型是一個免費的功能:

template<typename T, typename TList> 
AwesomeClass<T, TList> make_AwesomeClass(TList& tlist) 
{ 
    return AwesomeClass<T, TList>(tlist); 
} 

調用這種方式:

auto awesomeClass = make_AwesomeClass<int>(mylist); 
+0

函數'make_AwesomeClass'的模板參數扣除'T'將失敗。 – Snps

+0

@Snps:確實無法推斷出'T',但是你想從'mylist'推導出'TList'(並且我認爲'T'和'TList'是無關的,這在編輯後看起來不對)。 – Jarod42

+0

儘管我不是OP;) – Snps

1

我不t嗨,你需要兩個模板params。

template <class Container> 
class AwesomeClass { 
public: 
    // you can use this typedef to access the value type 
    typedef typename Container::value_type value_type; 
    AwesomeClass(Container &list): theList(&list) {} 
private: 
    Container *theList; 
    typename Container::iterator theiterator; 
}; 

int main() { 
    // you can use typedef if you like 
    typedef std::list<int> intList; 
    intList list{1, 2, 3}; 
    AwesomeClass<intList> newInt(list); 
} 
+0

儘管這可能是OP所需要的,但它相當於它們發佈的代碼 - 它將一個迭代器存儲到'TList'中,原始代碼具有'std :: list : :iterator'。不過,從我+1,我相信你設法掌握了實際意圖。 – Angew

+0

這看起來很完美,但我似乎得到了value_type的編譯錯誤。它不是全局命名空間的成員,顯然這是一個編譯器錯誤。我試過使用一種解決方法(添加到我的問題),但我在Iterator的聲明時出現錯誤 - 編譯器抱怨應該有一個';'在之前呢? – Stefan

+0

@Stefan,這很奇怪。如果在類定義之後添加缺少的分號,您的新類在[gcc](http://ideone.com/4jrp5R)(ideone)中編譯得很好。但是這個警告不應該指向'Iterator'行。 – user2079303

相關問題