문제

훨씬 더 큰 프로젝트에서 문제를 재현하는 다음의 최소한의 예를 고려하십시오.

spec.h :
#include <iostream>

class A
{
public:
    template<typename T>
    T test(const std::string& a)
    {
        std::cout << "DEFAULT CALLED WITH " << a << "\n";
        return T();
    }
};
.

other.cpp :
#include "spec.h"

template<>
float A::test<float>(const std::string& a)
{
    std::cout << "SPECIAL CALLED WITH " << a << "\n";
    return float();
}
.

spec.cpp :
#include <iostream>
#include "spec.h"

int main()
{
    A a;
    a.test<int>("int");
    a.test<float>("float");
    return 0;
}
.

컴파일 :
$ make
rm -f *.o lib.a output
clang++ -g other.cpp -c
clang++ -g spec.cpp -c
ar cr lib.a other.o
clang++ -g -o output lib.a spec.o
rm -f *.o output2
clang++ -g other.cpp -c
clang++ -g spec.cpp -c
clang++ -g -o output2 other.o spec.o

$ ./output
DEFAULT CALLED WITH int
DEFAULT CALLED WITH float

$ ./output2
DEFAULT CALLED WITH int
SPECIAL CALLED WITH float
.

질문 :

왜 이런 일이 일어나고 있습니까?어떻게 든 제거됩니까?lib.a와 직접 개체 파일 사용의 차이점은 무엇입니까?: -)

감사합니다!

도움이 되었습니까?

해결책

섹션 14.7.3p6 :

템플릿, 회원 템플릿 또는 클래스 템플릿의 구성원이 명시 적으로 전문화되어 있으면 모든 번역 단위에서 암시 적 인스턴스화를 일으킬 수있는 전문화의 첫 번째 사용 전에 전문화가 선언되어야합니다. 그러한 사용이 ; 진단이 필요하지 않습니다. 프로그램이 명시 적 전문화를 위해 제기하지 않고 암시 적 인스턴스화를 일으키거나 회원이 가상 멤버 함수이거나 회원이 가상 멤버 함수 인 경우에는 전문화가 사용됩니다.이 프로그램은 아프고 진단이 필요하지 않습니다.

해당 번역 단위에서 먼저 선언하지 않고 SPEC.CPP의 전문화를 사용했기 때문에 프로그램이 아프다. 또는 다음 단락은 다음과 같습니다.

함수 템플릿, 클래스 템플릿, 클래스 템플릿의 구성원 기능, 클래스 템플릿의 정적 데이터 구성원, 클래스 템플릿의 멤버 클래스, 클래스 템플릿의 멤버 클래스 템플릿, 멤버 함수 클래스 템플릿의 템플릿, 클래스 템플릿의 멤버 템플릿의 멤버 함수, 템플릿이 아닌 클래스의 구성원 템플릿의 멤버 함수, 클래스 템플릿의 멤버 함수 템플릿 및 클래스 템플릿의 부분 전문화 선언 배치 및 회원 클래스 템플릿 클래스의 클래스 템플릿, 클래스 템플릿 등의 멤버 클래스 템플릿 등은 프로그램이 명시 적 전문화 선언의 상대적 위치 지정 및 위와 같이 번역 단위의 인스턴스화 지점에 따라 프로그램이 잘 형성되었는지 여부에 영향을 미칠 수 있습니다. 아래.

전문화를 작성할 때




컴파일을 만들기 위해






전체 표준 에서 awesomest 단락 limerick로 투표하는

.

다른 팁

Ben Voigt의 답변 가 정확하지만 조금 더 많이 추가하고 싶습니다.

본질적으로 다른 버전의 기능, 즉 다른 버전의 기능을 가져옵니다. O.O (인라인 템플리트에서 생성).링커는 표준이 요구하는 것과 동일한 것과 동일하다고 가정하도록 하나와 오직 하나만 선택하도록 설계되었습니다.첫 번째 경우에 기호가 아직 정의되어 있지 않은 경우 링커가 라이브러리에서만 정의됩니다.SPEC.O에 정의 된 이래로 라이브러리 정의가 사용되지 않습니다.

헤더의 정의와 각 변환 유닛은 자체 인스턴스화를 만들 수 있습니다.따라서 전문 버전을 참조하는 정의되지 않은 기호가 아닙니다.그에 따라 라이브러리를 볼 때 특수 버전의 객체 파일이 포함되어 있지 않습니다. 정의되지 않은 기호를 정의하지 않습니다.링크하는 동안 객체 파일을 명시 적으로 포함 할 때 링커는이를 포함하는 것보다 선택 사항이 없습니다.그러나 모든 전문 분야를 선언해야합니다. 선언없이 컴파일러에는 일반 버전이 적용되지 않는다는 단서가 없습니다.이 버전이 사용되는지 여부는이 버전을 수행하므로 기호가 처리되는 방식에 따라 다릅니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top