2014-04-15 4 views
1

템플릿을 사용하는 방법을 배우기 위해 템플릿을 사용하는 예를 만들려고합니다.이 템플릿 예제 코드가 컴파일되지 않는 이유는 무엇입니까?

Controller.cpp :

#include <iostream> 

#include "Foo.h" 

using namespace std; 

int main(){ 

    Example<int,string> example; 

    example.appols(5, "Hi"); 

    return 0; 
} 

Foo.h :

#include <iostream> 

using namespace std; 

template <class T, class E> 
class Foo{ 
public: 
    void printThis(T t, E e); 
}; 

template <class T, class E> 
class Example{ 
public: 
    void appols(T t, E e); 
}; 

Foo.ipp : 나는 3 개 파일을 비주얼 스튜디오 2010 C++에서 프로젝트를 만든

#include <iostream> 

#include "Foo.h" 

using namespace std; 

template<class T, class E> 
void Foo<T, E>::printThis(T t, E e){ 
    cout << "FOO! " << t << ' ' << e << endl; 
} 

template<class T, class E> 
void Example<T, E>::appols(T t, E e){ 
    cout << "APPOLS!! " << t << ' ' << e << endl; 
    Foo<T,E> f; 
    f.printThis(t,e); 
} 

컴파일하려고하면 다음과 같이 나타납니다.

1>------ Build started: Project: Template Practive, Configuration: Debug Win32 ------ 
1>Controller.obj : error LNK2019: unresolved external symbol "public: void __thiscall Example<int,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >::appols(int,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" ([email protected][email protected][email protected][email protected]@[email protected]@[email protected]@[email protected]@[email protected]@@@[email protected][email protected]@[email protected]@[email protected]@[email protected]@[email protected]@@Z) referenced in function _main 
1>C:\Users\Matthew\documents\visual studio 2010\Projects\Template Practive\Debug\Template Practive.exe : fatal error LNK1120: 1 unresolved externals 
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ========== 

여기서 내가 잘못한 부분을 볼 수 있도록 도와 주시겠습니까? error LNK2019은 어디에서 왔습니까? 미리 감사드립니다.

+1

클래스 정의 뒤에'Foo.h'에'Foo.ipp'를 포함시켜야합니다. – juanchopanza

답변

5

의 첫 번째 에러 메시지를 디코딩하려고하자 오류 메시지

을 해독 : 우리는이 오류 메시지의 노이즈/신호 비율을 줄이기 위해 시작할 수 있습니다

1>Controller.obj : error LNK2019: unresolved external symbol 
"public: void __thiscall Example<int,class std::basic_string<char,struct 
std::char_traits<char>,class std::allocator<char> > >::appols(int,class 
std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" 
([email protected][email protected][email protected][email protected]@[email protected]@[email protected]@[email protected]@[email protected]@@@[email protected][email protected]@[email protected]@[email protected]@[email protected]@[email protected]@@Z) 
referenced in function _main 

.

부분은 ([email protected][email protected][email protected][email protected]@[email protected]@...입니다. C++ 이름 변경입니다. 이것은 C++ 컴파일러를위한 것이며 사람이 읽을 수있는 것이 아닙니다. 그래서 우리는 그냥 버릴 수 있습니다.

단순화 오류 메시지가된다 :

1>Controller.obj : error LNK2019: unresolved external symbol 
"public: void __thiscall Example<int,class std::basic_string<char,struct 
std::char_traits<char>,class std::allocator<char> > >::appols(int,class 
std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" 
referenced in function _main 

첫 번째 줄은 "확인되지 않은 외부 기호"이 있다는 것을 우리에게 알려줍니다. 다음 라인을 보면서 그것을 확인해 보도록하겠습니다.

부품 :

class std::basic_string<char,struct std::char_traits<char>... 

는 긴 (문자 유형으로 charstd::basic_string 템플릿에 해당하는 기본 char 특성과 기본 할당을 사용하여) std::string의 이름입니다.

그래서 우리는 더 대신 그 자세한 부분 std::string을 대체하여 노이즈를 줄일 수

1>Controller.obj : error LNK2019: unresolved external symbol 
"public: void __thiscall Example<int,string>::appols(int,string)" 
referenced in function _main 

지금 오류가 훨씬 명확하다.

__thiscall 부분은 C++ 멤버 함수에서 기본적으로 사용되는 호출 규칙입니다.

그래서, 링커는이 방법에 대해 불평 : 해당

"public: void Example<int,string>::appols(int,string)" 

당신의 Example<T,E>::appols()에 :

template <class T, class E> 
class Example{ 
public: 
    void appols(T t, E e); 
}; 

T=intE=std::string을.

이것은 당신이 Controller.cpp에 main() 기능이 무엇인지에 해당 문제

Example<int,string> example; 

example.appols(5, "Hi"); 

진단 및 해결이 문제는 모든이다 템플릿 소스 코드는 헤더 파일에 있어야합니다. .cpp 파일에서.

실제로 컴파일러는 인스턴스화하기 위해 템플릿 코드의 정의가 필요합니다.

그래서, 당신은 Foo.h에 Foo.ipp 파일의 코드를 이동할 수 있습니다 (또는 Foo.h에서 불과 #include "Foo.ipp") 및 템플릿 함수 정의에 inline을 추가

// New code in Foo.h 

template<class T, class E> 
inline void Foo<T, E>::printThis(T t, E e){ 
    cout << "FOO! " << t << ' ' << e << endl; 
} 

template<class T, class E> 
inline void Example<T, E>::appols(T t, E e){ 
    cout << "APPOLS!! " << t << ' ' << e << endl; 
    Foo<T,E> f; 
    f.printThis(t,e); 
} 

참고도 그 using namespace std; 헤더 파일에 정말 나쁜 이후 헤더를 포함하는 모든 클라이언트에 대한 전역 네임 스페이스를 오염시킬 것입니다. 헤더 파일에 std:: 접두어를 명시 적으로 사용하십시오 (예 : std::cout, std::endl 등).

관련 문제