이 질문을 이해하기 위해 이전 질문에서 얻은 훌륭한 대답을 사용하려고했지만 왜이 코드가 컴파일되지 않는지 이해할 수 없습니다.템플릿 템플릿 매개 변수를 사용하는이 함수가 컴파일되지 않는 이유는 무엇입니까?
stack8test.cpp: In function int main():
stack8test.cpp:28: error: no matching function for call to Pout(Stack<int, std::vector>&)
make: *** [stack8test.o] Error 1
내가 도움을 주셔서 감사합니다 :
#include <iostream>
#include <ostream>
#include <string>
#include <cstdlib>
#include <vector>
#include <memory>
template <typename T,
template <typename ELEM,
typename = std::allocator<ELEM> >
class CONT = std::deque>
class Stack {
public:
typedef typename CONT<T>::size_type size_type;
private:
CONT<T> elems; // elements
public:
void push(T const&); // push element
void pop(); // pop element
T top() const; // return top element
bool empty() const { // return whether the stack is empty
return elems.empty();
}
size_type size();
};
template <typename T, template <typename,typename> class CONT>
void Stack<T,CONT>::push (T const& elem)
{
elems.push_back(elem); // append copy of passed elem
}
template<typename T, template <typename,typename> class CONT>
void Stack<T,CONT>::pop()
{
if (elems.empty()) {
throw std::out_of_range("Stack<>::pop(): empty stack");
}
elems.pop_back(); // remove last element
}
template <typename T, template <typename,typename> class CONT>
T Stack<T,CONT>::top() const
{
if (elems.empty()) {
throw std::out_of_range("Stack<>::top(): empty stack");
}
return elems.back(); // return copy of last element
}
template<typename T,
template<typename, typename= std::allocator<T> > class CONT>
typename Stack<T, CONT>::size_type Stack<T, CONT>::size()
{
return elems.size();
}
template <typename T,
template <typename ELEM, typename = std::allocator<ELEM> > class CONT>
static inline void Pout(const CONT<T>& container)
{
typedef typename CONT<T >::size_type size_type;
size_type idx = 0;
size_type sz = CONT<T>::size();
CONT<T> temp = container;
std::cout << '[';
while (idx < sz)
{
std::cout << temp.top();
temp.pop();
idx++;
if (idx == sz) break;
std::cout << ", ";
}
std::cout << "]";
}
int main()
{
try {
Stack<int, std::vector > vStack;
//...
vStack.push(42);
vStack.push(7);
Pout<Stack<int, std::vector > >(vStack);
}
catch (std::exception const& ex) {
std::cerr << "Exception: " << ex.what() << std::endl;
}
}
나는 ++ 4.3.4 g을 사용하여 컴파일러 오류가 발생합니다.
함수 호출을 Pout> (vStack)으로 주석 처리하고 vStack의 내용을 std :: cout으로 출력하도록 변경했습니다. 다음은 새로운 코드입니다. 그것은 컴파일하고 예상대로 작동합니다
#include <iostream>
#include <ostream>
#include <string>
#include <cstdlib>
#include <vector>
#include <memory>
#include <deque>
#include <stdexcept>
template <typename T,
template <typename ELEM,
typename = std::allocator<ELEM> >
class CONT = std::deque>
class Stack {
public:
typedef typename CONT<T>::size_type size_type;
typedef typename CONT<T>::value_type value_type;
private:
CONT<T> elems; // elements
public:
void push(T const&); // push element
void pop(); // pop element
T top() const; // return top element
bool empty() const { // return whether the stack is empty
return elems.empty();
}
size_type size();
void Pout();
};
template <typename T, template <typename,typename> class CONT>
void Stack<T,CONT>::push (T const& elem)
{
elems.push_back(elem); // append copy of passed elem
}
template<typename T, template <typename,typename> class CONT>
void Stack<T,CONT>::pop()
{
if (elems.empty()) {
throw std::out_of_range("Stack<>::pop(): empty stack");
}
elems.pop_back(); // remove last element
}
template <typename T, template <typename,typename> class CONT>
T Stack<T,CONT>::top() const
{
if (elems.empty()) {
throw std::out_of_range("Stack<>::top(): empty stack");
}
return elems.back(); // return copy of last element
}
template<typename T,
template<typename, typename= std::allocator<T> > class CONT>
typename Stack<T, CONT>::size_type Stack<T, CONT>::size()
{
return elems.size();
}
template <typename T,
template<typename, typename = std::allocator<T> > class CONT>
void Stack<T, CONT>::Pout()
{
size_type idx = 0;
size_type sz = size();
CONT<T> temp(elems); // make a temp copy of the underlying container and print the temp, since printing is destructive. Note that the underlying CONT must already support copy constructor.
std::cout << std::endl << '[';
while (idx < sz)
{
std::cout << temp.back();
temp.pop_back();
idx++;
if (idx == sz) break;
std::cout << ", ";
}
std::cout << "]" << std::endl;;
}
template <typename T,
template <typename ELEM, typename = std::allocator<ELEM> > class CONT>
void Pout(const CONT<T>& container)
{
typedef typename CONT<T >::size_type size_type;
size_type idx = 0;
size_type sz = CONT<T>::size();
CONT<T> temp = container;
std::cout << '[';
while (idx < sz)
{
std::cout << temp.top();
temp.pop();
idx++;
if (idx == sz) break;
std::cout << ", ";
}
std::cout << "]";
}
int main()
{
try {
Stack<int, std::vector > vStack;
//...
vStack.push(42);
vStack.push(7);
// Pout<Stack<int, std::vector > >(vStack);
vStack.Pout();
std::cout << "vStack = [" << vStack.top(); vStack.pop();
std::cout << ", " << vStack.top() << "]" << std::endl; vStack.pop();
}
catch (std::exception const& ex) {
std::cerr << "Exception: " << ex.what() << std::endl;
}
}
컴파일러의 출력은 다음과 같습니다
g++ -O2 -g -Wall -c -o stack8test stack8test.cpp
프로그램을 실행, 내가 가지고 :
./stack8test
vStack = [7, 42]
내 진짜 문제는 대한 올바른 구문을 찾는 것입니다 함수 템플릿 Pout 내 클래스 템플릿 Stack의 내용을 출력합니다. 명확히하기 위해, 클래스 템플릿 Stack을 T 타입의 요소 컨테이너로 구현하는 것입니다. std :: vector 또는 std :: deque 형식의 std 컨테이너 또는 Std :: list의 관점에서 Stack을 구현하고 싶습니다. .
나는대로 메기라고 :Pout<int, Stack<int, std::vector>>(vStack);
그러나 컴파일러는 여전히 말한다 :
stack8test.cpp: In function int main():
stack8test.cpp:137: error: no matching function for call to Pout(Stack<int, std::vector>&)
make: *** [stack8test.o] Error 1
UPDATE : 글로벌의 내 원래 원래 문제에 대한 주위의 작품으로 (즉, 비회원) 함수는 내 스택의 내용을 std :: cout으로 출력하기 위해 Pout()을 멤버 함수로 정의했다. 그것은 컴파일하고 예상대로 작동합니다. 전역 함수에 대한 올바른 구문을 찾는 것은 여전히 어려운 과제입니다.
'std :: deque'를 사용하면 헤더도 포함해야합니다 (). –
dyp
더 일찍 언급하지 않으셔서 죄송합니다. 나는 아프다. – user2975538
죄송합니다. 나는 아프다. 내 디자인을 잘 모르겠다. Stack은 STL 컨테이너 중 하나 (vector 또는 deque)로 구현할 수있는 클래스 템플릿 컨테이너이다. 합리적인 디자인이라고 생각합니다. @Mikhail – user2975538