0

.h 파일 대신 .cpp 파일에 정의 된 일부 메서드로 템플릿 클래스가있는 경우 명시 적 인스턴스화를 사용하여 해결되지 않은 외부를 피하기 위해 컴파일러를 가져올 수 있습니다.템플릿 명시 적 인스턴스화가 forward-declared-types과 작동합니까?

그러나 명시 적 인스턴스화가 전달 선언 유형을 사용하여 선언 된 경우 작동합니까? A가 마지막으로 정의되어 있지 및 Template<A>를 사용하지 않는 경우

template <typename T> struct Template 
{ 
    void someFunc(); //defined in the .cpp file 
} 

class A; 

template Template<A>; 

은 작동겠습니까?

+0

템플릿을 분할하지 말고 모두 헤더 파일에 정의하십시오. – NathanOliver

+0

여기에 'A'를 쓰지 않아도되므로 아무런 문제가 없습니다. – Quentin

+0

@Quentin : 답변 해 주셔서 감사합니다. 이 코드가 라이브러리의 일부인 경우 템플릿 :: someFunc() 기호는 lib에 내 보내지 만 나중에 정의되지 않은 외부의 원인이되지 않습니다. – Michel

답변

1

우선. 컴파일러는 템플릿이 인스턴스화 된 경우에만 코드를 생성합니다 (예제에서는 인스턴스화가 없으므로 코드가 생성되지 않습니다). 둘째, 형식 템플릿 인수를 전달합니다. 여기서 컴파일러는 안전하게 인스턴스를 생성 할 수 있습니다. 예에서는 유형을 어딘가에서 사용하지 않지만 예를 들어 함수를 정의하기 위해 첫 번째 문장을 다시 적용하고 함수는 어딘가에 인스턴스화 될 때 생성됩니다. 이 순간 컴파일러는 코드를 생성하는 데 필요한 모든 지식을 갖추고 있어야합니다.

// Example program 
#include <iostream> 


template <typename T> struct Template 
{ 
    void someFunc(); //defined in the .cpp file 
}; 

class A; 
Template<A> foo; 

그러나 형식이 아닌 매개 변수를 사용하는 템플릿을 만드는 경우. 당신이 염려했던 것처럼 형식 정의가 불완전하기 때문에 실패 할 것입니다.

// Example program 
#include <iostream> 
#include <string> 

class A; 

template <A parm> struct Template 
{ 
    void someFunc() { 
     parm.foo(); 
    } 
}; 

A a; 
using foo = Template<a>; 

이 예제와 동일합니다. 여기서 객체 a을 만들고 물론 컴파일러는 그 유형에 대해 더 알고 있어야합니다. 이것이 실패하는 이유입니다.

// Example program 
#include <iostream> 


template <typename T> struct Template 
{ 
    T a; 
}; 

class A; 
Template<A> foo; 

희망이 도움이됩니다.

+0

나는 다른 프로젝트에서 새로운 유형을위한이 템플릿의 전문화를 정의 할 때 (예상대로) 해결되지 않은 외부 함수를 가지고 있었다. 몸에 정의되어 있습니다. 그래서 다른 프로젝트에서 필자는이 템플리트를 효과적으로 사용하고 있었지만 템플리트 정의시 존재하지 않았던 기호로 lib 파일이 작성되기 전에 정의되지 않았습니다. 그 전방 정의 속임수로, 나는 더 이상 해결되지 않은 외부를 가지고 있지 않으며 왜 나는 궁금합니다. 템플릿 함수의 본문은 크기가 알려 지도록 cpp에 있어야한다고 생각했습니다. – Michel

관련 문제