(C++ : Template) lazy instantiation

Posted by : at

Category : Cpp


class A
{
    int data;
public:
    void foo(int n) { *n = 10; }        
    // error - 역참조가 불가능!, 빌드자체가 안된다
    // 에러가 나오게 만듦
};

int main()
{
    A a;
}
template<typename T>
class A
{
    T data;
public:
    void foo(T n) { *n = 10; }        
    // ok - 아직은 foo를 사용하지 않았기에 컴파일은 된다. 
    //    -> lazy instantiation이라 한다.
};

int main()
{
    A<int> a;
    a.foo(0);       // error : 사용하면 에러리턴
}

어떻게 보면 주의사항이라 할 수 있는 점.
template으로 생성시 컴파일타임에 코드가 결정이 나는게 아니라 런타임에 코드가 결정나기에 에러를 발생할 수 있다.


생성순서?

#include <iostream>
using namespace std;

struct Resource1
{
    Resource1() { cout << "Resource1()" << endl;}
    ~Resource1() { cout << "~Resource1()" << endl;}
};

struct Resource2
{
    Resource2() { cout << "Resource2()" << endl;}
    ~Resource2() { cout << "~Resource2()" << endl;}
};

struct Test
{
    Resource1 res1;
    static Resource2 res2;
};
Resource2 Test::res2;           // 1. 생성자 호출

int main()
{
    cout << "main" << endl;     // 2. main 함수 호출
    Test t;                     // 3. 생성자 호출
}
$ Resource2()   # static으로 선언된 Resource2가 main보다 먼저 생성된다.
$ main
$ Resource1()   # Test 생성시점에 Resource1이 생성.
$ ~Resource1()
$ ~Resource2()  # 소멸은 제일 마지막..
template<typename T> struct Test
{
    Resource1 res1;
    static Resource2 res2;
};
template<typename T> Resource2 Test<T>::res2;

int main()
{
    cout << "main" << endl;             // 1. main 함수 호출
    Test<int> t;                        // 2. 생성자 호출
}
$ main
$ Resource1()
$ ~Resource1()
$ # 사용한적 없는 Resource2는 호출이 되지 않는다.
template<typename T> void foo(T n)
{
    *n = 10;
}

int main()
{
    if(false)
        foo(0);     // 인스턴스화 될 것인가?
                    // if문은 실행시간에 결정이 되기에 우선은 인스턴스화가 된다.

    if constexpr (false)
        foo(0);     // 요거는 인스턴스화가 안됨.
}
template<typename T> void foo(T n, int)
{
    *n = 3.4;
}

template<typename T> void foo(T n, double)
{

}

int main()
{
    foo(1, 3.4);        // template<typename T> void foo(T n, double)
    // 이 결정을 컴파일 시간에 할까 실행시간에 할까??
    // 만약 실행 시간에 한다면 foo 두 함수 모두 메모리에 올라갈 것!
    // 결론은 컴파일 시간에 한다 template<typename T> void foo(T n, int)는 메모리에 올라가지 않기에 컴파일이 된다.
}

About Taehyung Kim

안녕하세요? 8년차 현업 C++ 개발자 김태형이라고 합니다. 😁 C/C++을 사랑하며 다양한 사람과의 협업을 즐깁니다. ☕ 꾸준한 자기개발을 미덕이라 생각하며 노력중이며, 제가 얻은 지식을 홈페이지에 정리 중입니다. 좀 더 상세한 제 이력서 혹은 Private 프로젝트 접근 권한을 원하신다면 메일주세요. 😎

Star
Useful Links