사용하지 않은 템플릿 클래스 방법에 대해 객체 코드가 생성됩니까?

StackOverflow https://stackoverflow.com/questions/183108

  •  06-07-2019
  •  | 
  •  

문제

3 가지 유형 매개 변수로 인스턴스화되는 C ++ 템플릿 클래스가 있습니다. 클래스는 이러한 유형 중 하나에 대해서만 필요한 방법이 있으며 다른 두 가지 유형으로 호출되지 않는 방법이 있습니다.

해당 메소드의 객체 코드는 3 회 생성됩니까 (템플릿이 인스턴스화되는 모든 유형에 대해), 또는 객체 코드가 한 번만 생성됩니까 (실제로 사용되는 유형의 경우)?

도움이 되었습니까?

해결책

가상 멤버 기능은 클래스 템플릿이 인스턴스화 될 때 인스턴스화되지만, 비 사건 멤버 함수는 호출되는 경우에만 인스턴스화됩니다.

이것은 C ++ 표준 (C ++ 11에서 §14.7.1/10입니다. C ++ 14에서는 §14.7.1/11이고 C ++ 17입니다. §17.7.1/9입니다. 아래 C ++ 17에서 발췌)

구현은 함수 템플릿, 변수 템플릿, 멤버 템플릿, 비 빈자 멤버 함수, 멤버 클래스, 클래스 템플릿의 정적 데이터 구성원 또는 constexpr 그러한 인스턴스화가 필요하지 않는 한 if 문 (9.4.1)

또한 부재 함수 중 일부가 주어진 템플릿 매개 변수에 대해 인스턴스화되지 않더라도 클래스 템플릿을 인스턴스화 할 수 있습니다. 예를 들어:

template <class T>
class Xyzzy
{
public:
    void CallFoo() { t.foo(); }  // Invoke T::foo()
    void CallBar() { t.bar(); }  // Invoke T::bar()

private:
    T t;
};

class FooBar
{
public:
    void foo() { ... }
    void bar() { ... }
};

class BarOnly
{
public:
    void bar() { ... }
};

int main(int argc, const char** argv)
{
    Xyzzy<FooBar>  foobar;    // Xyzzy<FooBar> is instantiated
    Xyzzy<BarOnly> baronly;   // Xyzzy<BarOnly> is instantiated

    foobar.CallFoo();         // Calls FooBar::foo()
    foobar.CallBar();         // Calls FooBar::bar()

    baronly.CallBar();        // Calls BarOnly::bar()

    return 0;
}

xyzzy :: callfoo ()가 Baronly :: foo ()와 같은 것은 없기 때문에 인스티니 불가능하지만 유효합니다. 이 기능은 종종 템플릿 메타 프로 그램 툴로 사용됩니다.

그러나 템플릿의 "인스턴스화"는 객체 코드가 생성되는 양과 직접적으로 관련이 없음을 주목하십시오. 이는 컴파일러/링커 구현에 따라 다릅니다.

다른 팁

컴파일러와 설정에 달려 있다고 생각합니다. 예를 들어, MSVC6이 모든 것을 생성했다고 생각하지만 vs2005는 그렇지 않습니다. 사양은 컴파일러가 말하지 않아야하지만 실제 세계에서는 실제 컴파일러에 따라 다르다고 말합니다 (예를 들어 MSVC6의 부스트에는 많은 워크 어라운드가 있습니다). 링커는 /opt : ref가 활성화 된 경우 참조되지 않은 함수를 제거 할 수 있습니다 (VS의 경우 다른 컴파일러의 경우 동등한 옵션이 존재 함).

일반적으로 그렇습니다.

모든 컴파일러는 프로그램이 각 클래스의 적어도 하나의 인스턴스를 생성 할 수 있다는 것입니다. 그러나 그러한 사례로 무엇을할지 모르겠습니다. 따라서 코드는 거의 확실하게 생성됩니다.

문제의 방법이 있다면 ~ 아니다 가상, 결코 호출되지 않습니다 링커 일반적인 데드 코드 제거 기능으로 제거 할 수 있습니다. 따라서 생성 된 (및 컴파일 된) 코드는 최종 EXE에 없습니다.

또한 이것은 모두 동일하지 않기 때문에 사용중인 C ++ 컴파일러에 크게 의존합니다.

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