2011-08-26 95 views
0

這裏是我的代碼:實例化模板類<erroneous-expression>?

template<typename T, template<typename = T,typename =std::allocator<typename = T> > class Container= std::vector> 
class stack 
{ 
    public: 
    Container<T> cont; 
    stack() 
    { 

    } 
}; 

如果我更換代碼的第一行下面的代碼,然後它的工作原理:

template<typename T, template<typename elem= T,typename =std::allocator<elem> > class Container= std::vector> 

,但我要問的是我讀過的時候你不不使用模板類型參數,那麼你可以這樣寫:<typename=default_type><typename>。上述代碼中的T也可以在模板模板參數Container的參數列表中看到(即,在整個參數化子句中可以看到類型參數T)。總而言之,我認爲它應該起作用。 但是它沒有,並給出了錯誤:

error: expression '<erroneous-expression> = <erroneous-expression>' is not a constant-expression 
error: template argument 1 and 2 are invalid 

因此,誰能解釋爲什麼我看到這些錯誤,什麼是錯誤的表達?

+0

「錯誤表達」可能只是你的編譯器被困惑。 –

回答

1

當模板參數本身是一個模板時,除了定義模板參數的「模板簽名」之外,其自身的模板參數在外模板的上下文中不被使用或不相關。因此,您不需要任何參數名稱,因爲它們不可用或不必要。你可以簡單地這樣說:

template <typename T, template<typename, typename> class Container = std::vector> 
class stack 
{ 
    typedef Container<T, std::allocator<T> > CT; 
    // ... 
}; 

這裏template <typename, typename>就是您所期望的Container模板類的模板簽名。

在C++ 11,你可以做的更好,使用可變參數模板讓更多的普通集裝箱:

template <typename T, template<typename...> class Container = std::vector> class stack; 

[出於完整性:]把默認類型模板參數的參數列表也適用,它意味着你可以在以後忽略這些類型(因爲你已經這樣做):

template<typename = T, typename = std::allocator<T> > class Container 

---> now we can say: 

Container<T> x; // use second default argument 
Container<> y; // use both default arguments 

要回答喲烏爾問題:你想在

template <typename = T, typename = std::allocator<typename> > class Container 
            ^^^^^^^^^^^^^^^^^^^^^^^^ 
              Error!! 

std::allocator<typename>指定一個默認類型不是一個類型 - 它甚至沒有合法的語法。你既可以有一個模板參數,再次是一個模板,即template <typename> = std::allocator,但不會通過std::vector匹配,或者你有一個實際的類型:

template <typename = T, typename = std::allocator<T> > class Container 
            ^^^^^^^^^^^^^^^^^ 
            OK, this is a type 
+0

你還沒有回答爲什麼我的代碼(非常第一個代碼塊的第一行)不起作用? –

+0

第二個嵌套的默認類型'typename = std :: allocator '不起作用,因爲這不是一個類型,而是一個模板。你應該說'typename = std :: allocator ',因爲這是一個類型。 –

+0

謝謝Kerrek好和**解釋**答案),順便說一句考慮你的答案編輯,因爲我的行是** std :: allocator ** –

0

在類模板的參數列表,當您指定模板的模板參數,那麼不使用模板的模板參數的模板參數(事實上,他們不能使用)。因此,您可以跳過提及他們的名字。

那麼你應該做的是:

template<typename T, template<class,class> class Container= std::vector> 
class stack 
{ 
    Container<T, std::allocator<T> > cont; 
}; 

也就是說,所有需要的模板的模板參數是參數(S)的數量,信息什麼的參數( s):類型或值。

你也可以這樣寫爲更好的可讀性:

template<typename T, template<class U,class Allocator> class Container= std::vector> 
class stack 
{ 
    Container<T, std::allocator<T> > cont; 
}; 

至於爲什麼你的第一個代碼是不工作的,因爲std::allocator<typename = T>這應該是簡單的std::allocator<T>。也就是說,這應該工作:

template<typename T, template<typename =T,typename =std::allocator<T> > class Container= std::vector> 

見這裏:http://ideone.com/eO8qT

但後來這種默認類型的模板的模板參數甚至沒有考慮。他們被忽略。

現在你可能會問爲什麼std::allocator<typename =T>不起作用。因爲它形成不良。你認爲std::vector<typename =T>有意義嗎?請注意0​​和std::vector都是類模板,但Container不是類模板。它是一個類模板的模板模板參數。這就是爲什麼,typename =T被允許用於此,而不允許用於類別模板,如std::allocator

+0

你還沒有回答爲什麼我的代碼(非常第一個代碼塊的第一行)不工作? –

+0

是否意味着「那麼**模板模板參數的模板參數**沒有被使用(實際上,它們不能被使用)」? –

+0

@Mr。阿努比斯:現在我解釋一下。你應該寫簡單的'std :: allocator ',而不是'std :: allocator '。 – Nawaz