![](/img/trans.png)
[英]Why does std::array require the size as a template parameter and not as a constructor parameter?
[英]Why does std::stack not use template template parameter?
為什么std::stack
和std::queue
使用類型模板參數而不是模板模板參數作為其底層容器類型?
即為什么stack
聲明如下:
template<typename T, typename Container = deque<T>>
class stack;
但不是這樣的:
template<typename T, template<typename> class Container = deque>
class stack;
?
因為像std::vector
這樣的容器通常有多個模板參數 。 通過不關心它是一個模板,你允許使用每種容器。
怎么會
template<class T, class Allocator = std::allocator<T>> class vector;
適合
template<typename> class Container
就像你在stack
? (提示:它沒有!)你需要特殊情況來處理你想要支持的每個數字和類型的模板參數(類型與非類型),這很愚蠢,因為這些通常不會貢獻任何比簡單更多的信息
typename Container
請注意,要獲得例如std::vector
的實際模板參數,您可以使用typedefs std::vector::value_type
和std::vector::allocator_type
,從而無需在實際使用時明確提供這些類型類型(即stack
的Container
)。
簡而言之:因為使用模板模板參數比使用類型參數更具限制性*而不提供任何優勢。
* 限制性我的意思是你可能需要一個更復雜的東西來獲得與“簡單”類型參數相同的結果。
為什么沒有優勢?
你的std::stack
可能有這樣的屬性:
template <typename T, typename Container>
struct stack {
Container container;
};
如果您通過模板模板參數替換Container
,您為什么會獲得?
template <typename T, template <typename...> class Container>
struct stack {
Container<T> container;
};
您只實例化一次Container
,僅用於T
( Container<T>
),因此模板模板參數沒有任何優勢 。
為什么它更具限制性?
使用模板模板參數,您必須向std::stack
傳遞一個公開相同簽名的模板,例如:
template <typename T, template <typename> class Container>
struct stack;
stack<int, std::vector> // Error: std::vector takes two template arguments
也許你可以使用可變參數模板:
template <typename T, template <typename... > class Container>
struct stack {
Container<T> container;
};
stack<int, std::vector> // Ok, will use std::vector<int, std::allocator<int>>
但是如果我不想使用標准的std::allocator<int>
怎么辦?
template <typename T,
template <typename....> class Container = std::vector,
typename Allocator = std::allocator<T>>
struct stack {
Container<T, Allocator> container;
};
stack<int, std::vector, MyAllocator> // Ok...
這變得有點亂......如果我想使用自己的容器模板需要3/4 / N參數怎么辦?
template <typename T,
template <typename... > class Container = std::vector,
typename... Args>
struct stack {
Container<T, Args...> container;
};
stack<int, MyTemplate, MyParam1, MyParam2> // Ok...
但是,如果我想使用非模板化容器怎么辦?
struct foo { };
struct foo_container{ };
stack<foo, foo_container> // Error!
template <typename... >
using foo_container_template = foo_container;
stack<foo, foo_container_template> // Ok...
使用類型參數沒有這樣的問題1 :
stack<int>
stack<int, std::vector<int, MyAllocator<int>>
stack<int, MyTemplate<int, MyParam1, MyParam2>>
stack<foo, foo_container>
1還有其他情況不適用於模板模板參數,例如使用模板接受特定順序中的類型和非類型參數的混合,您可以為其創建通用模板模板參數,甚至使用可變參數模板。
使用模板模板參數會將可用作底層容器的類型限制為公開相同模板簽名的類型。 只要這些表單支持預期的接口,它就允許任意類型。
因為它不編譯 :
std::deque
不是類型
template <typename T> class std::deque
它的類型
template<class T, class Alloc> class std::deque
這當然是一個更普遍的問題:即使我們要向我們的stack
類模板提供Alloc
模板參數,該類現在只能使用具有兩個類型模板參數的容器。 這是一個不合理的限制。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.