Stack<std::pair< int, int>> ps; // std::pair<> has no operator<< defined ps.push({4, 5}); // OK ps.push({6, 7}); // OK std::cout << ps.top().first << '\n'; // OK std::cout << ps.top().second << '\n'; // OK std::cout << ps << ’\n’; // ERROR: operator<< not supported for element type
template <> classStack<std::string> { private: std::deque<std::string> elems; // elements
public: voidpush(std::string const&); // push element voidpop(); // pop element std::string const &top()const; // return top element boolempty()const { // return whether the stack is empty return elems.empty(); } };
但是,如果我们按值传递模板参数
T
的话,参数类型就会被
decay
,也就是将
raw array
转换为相应的
raw pointer
。这样,调用带有模板参数
T
的构造函数就会将模板参数
T
的类型推导成
char const*
,模板也被推导为
Stack<char const*>
。
基于以上原因,可能有必要讲构造函数声明成按值传递参数的形式:
1 2 3 4 5 6 7 8 9 10
template <typename T> classStack { private: std::vector<T> elems; // elements public: Stack (T elem) // initialize stack with one element by value : elems({elem}) {} // to decay on class tmpl arg deduction ... };
这样下面的初始化方式就可以正常运行:
1
Stack stringStack = "bottom"; // Stack<char const*> deduced since C++17
template <typename T> classStack { private: std::vector<T> elems; // elements public: Stack (T elem) // initialize stack with one element by value : elems({std::move(elem)}) {} ... };