템플릿의 추론된 형식을 간편하게 확인

8587 단어 C++C++11C++14

템플릿을 작성하고 추론 된 유형을 확인하고 싶습니다.



템플릿을 작성하면
"이 인수를 주었을 때에는 T 가 어떻게 추론되는 것인가?"
뭐라고 생각하는 것이 좋지요?

嗚呼, 그럴 때, 어떻게 하면 좋을까요?

예를 들면
template < typename T >
void f(T&&){}

void g(int const&){};

int main(){
    f(g);
}

이 경우의 T 가 어떻게 추론되는지 알고 싶다!
라고 생각했을 때, 어떻게 합니까?
  • 포기
  • IDE에 의존
  • typeid.name () 사용
  • Boost.Typeindex 사용
  • Attribute 사용 (C++14)

  • IDE에 의존



    포커스를 하면 정보가 표시되는 것을 이용
    IDE를 사용하는 경우 일반적으로 이것으로 충분합니다.


    typeid.name() 사용



    헤더를 포함하여
    이 방법은 런타임까지 모르는 유형 정보를 표시 할 수 있기 때문에RTTI(Run Time Type Identifier) 라고 불린다
    #include <iostream>
    #include <typeinfo>
    using namespace std;
    
    template < typename T >
    void f(T&&){ cout << typeid(T).name() << endl;}
    
    void g(int const&){};
    
    int main(){
        f(g);
    }
    

    실행 결과

    FvRKiE

    죄송합니다 ...

    아니, 뭐야 이 문자열은! !

    typeid로 얻을 수 있는 형명은 그대로는 망글되어 있어
    쉽게 읽을 수 없기 때문입니다 (Microsoft 컴파일러는 읽을 수있는 문자열을 반환합니다)
    망설이려면 다음과 같이
    #include <iostream>
    #include <typeinfo>
    #include <cxxabi.h>
    using namespace std;
    
    template < typename T >
    void f(T&&){
        const type_info& id = typeid(T);
        int stat;
        char *name = abi::__cxa_demangle(id.name(),0,0,&stat);
        if( name!=NULL ) {
            if( stat==0 ) {    // ステータスが0なら成功
                printf("T = %s",name);
            }
            free(name);        // freeする必要がある
        }
    }
    
    void g(int const&){};
    
    int main(){
        f(g);
    }
    

    Boost.Typeindex



    Boost.Typeindex를 사용하면 환경에 따라 망글링되거나
    하지 않거나 하지 않는 것 같다
    #include <iostream>
    #include <boost/type_index.hpp>
    using namespace std;
    
    template < typename T >
    void f(T&&){ cout << boost::typeindex::type_id_with_cvr<T>().pretty_name() << endl;}
    
    void g(int const&){};
    
    int main(){
        f(g);
    }
    

    실행 결과

    void (&)(int const&)

    죄송합니다 ...

    하지만 잠시만 기다려
    이것은 귀찮지 않습니까?

    더 쉬운 방법이 C++14에는 존재한다

    Attribute [[deprecated]]


    [[deprecated]] 지정해 버리는 것이다!
    그렇게 하면 비추천된 함수가 사용되었다는 것을 깨달은 컴파일러는
    경고문을 내다
    그래, 인수의 형명도 동시에 표시해 준다!
    template < typename T >
    [[deprecated]] void f(T&&){}
    
    void g(int const&){};
    
    int main(){
        f(g);
    }
    

    경고문
    prog.cc: In function 'int main()':
    prog.cc:8:8: warning: 'void f(T&&) [with T = void (&)(const int&)]' is deprecated [-Wdeprecated-declarations]
         f(g);
            ^
    
    >prog.cc:3:21: note: declared here
     [[deprecated]] void f(T&&){}
                         ^
    

    이 방법으로 헤더를 포함하는 것도
    디버그 출력을 쓰는 것도
    더 이상 필요하지 않습니다! !

    좋은 웹페이지 즐겨찾기