2010-05-20 3 views
4

typeid (즉, typeid (int), typeid (std :: string) ...)와 함께 사용할 때 typeid가 컴파일 타임에 평가되는지 확인하고 싶습니다.형식 이름의 typeid는 항상 C++에서 컴파일 타임에 평가됩니까?

그렇게하기 위해 컴파일러에서 루프를 간소화했는지 확인하기 위해 두 개의 typeid 호출을 루프로 반복하고 최적화를 사용하여 컴파일했습니다 (실행 시간을 단순화 할 때 1us를보고 160ms가 아니라).

그리고 때때로 컴파일러가 코드를 단순화하기 때문에 이상한 결과를 얻습니다. 때로는 그렇지 않습니다. 나는 (나는 다른 4.x의 버전을 시도) ++ g을 사용하고, 여기에 프로그램입니다 :

#include <iostream> 
#include <typeinfo> 
#include <time.h> 

class DisplayData {}; 

class RobotDisplay: public DisplayData {}; 
class SensorDisplay: public DisplayData {}; 

class RobotQt {}; 
class SensorQt {}; 

timespec tp1, tp2; 
const int n = 1000000000; 

int main() 
{ 
    int avg = 0; 
    clock_gettime(CLOCK_REALTIME, &tp1); 
    for(int i = 0; i < n; ++i) 
    { 
//  if (typeid(RobotQt) == typeid(RobotDisplay)) // (1) compile time 
//  if (typeid(SensorQt) == typeid(SensorDisplay)) // (2) compile time 
     if (typeid(RobotQt) == typeid(RobotDisplay) || 
      typeid(SensorQt) == typeid(SensorDisplay)) // (3) not compile time ???!!! 
      avg++; 
     else 
      avg--; 
    } 
    clock_gettime(CLOCK_REALTIME, &tp2); 
    std::cout << "time (" << avg << "): " << 
     (tp2.tv_sec-tp1.tv_sec)*1000000000+(tp2.tv_nsec-tp1.tv_nsec) << 
     " ns" << std::endl; 
} 

이 문제가 나타나지 명확하지 않지만있는 조건 :
- 반군 상속이없는 경우, 문제
(항상 컴파일 시간) - 난 단지 하나 개의 비교, 아무 문제를한다면
이 - 모든 조건이 거짓 경우 문제는 비교의 분리 만 나타납니다

그래서하지 않았다 무언가가있다 typeid가 작동하는 방법 (type nam과 함께 사용될 때 항상 컴파일 타임에 평가되어야한다고 생각한다. es?) 또는 평가 또는 최적화에서 gcc 버그 일 수 있습니까?

컨텍스트에 대해이 간단한 예제를 사용하여 문제를 추적했지만 내 목표는 템플릿 유형에 typeid를 사용하는 것입니다 (부분 함수 템플릿 특수화는 불가능 함).

도움 주셔서 감사합니다.

+0

코드를 실행하는 데 얼마나 오래 걸릴지에 대한 결론을 내리고 있습니까? 아니면 컴파일러가 실제로 출력하고 있는지에 대한 확실한 증거가 있습니까? –

+0

'typeid'가 없어도 프로그램을 디자인 할 수 있습니까? 객체 유형을 비교하는 프로그램은 잘못 형성된 OO 프로그램으로 간주됩니다. –

+0

Dennis> 예, 방금 asm 코드를 확인한 결과 두 번의 clock_gettime 호출 사이에 점프가없는 6 가지 명령어가 있고 다른 명령어에서는 명확한 루프를 포함하여 2 가지 점프가 포함 된 15 가지 명령어가 있음을 확인할 수 있습니다. – cyril42e

답변

7

질문에 대한 답을 정말로 모르지만 typeid 대신 is_same <> 메타 기능을 사용하면 더 바람직한 결과를 얻을 수 있습니다. 이 metafunction에 액세스 할 수없는 경우에도, 쓰기 매우 쉽게 하나


template < typename T1, typename T2 > 
struct is_same 
{ 
    enum { value = false }; // is_same represents a bool. 
    typedef is_same<T1,T2> type; // to qualify as a metafunction. 
}; 

template < typename T > 
struct is_same 
{ 
    enum { value = true }; 
    typedef is_same<T,T> type; 
}; 
+0

멋진! 가 [템플릿 <유형 이름이 T>는 구조체 is_same ] [경우 (is_same :: 값) {}] 그리고있다 : 그러나 나는 일을 위해 조금에게 기능을 수정했다 boost :: is_same. 정말 고마워, 그럴거야! – cyril42e

2

typeid은 유용 무엇을 제안하는 런타임 형식 식별 메커니즘의 일부입니다 : 그것은 주요 사용법은이다 런타임시 기본 클래스에 대한 포인터/참조의 동적 유형을 식별합니다. 유형이 컴파일 타임에 정적으로 알려지면, 유형을 이미 알고있는 것처럼 유형을 "식별"할 필요가 없습니다.

예제에서 런타임에 식별 할 수있는 것은 없지만 컴파일 타임에 결과가 아무런 의미가 없습니다 (typeid은 템플릿 메타 프로그래밍에 필요한 const 표현식에 나타날 수 없습니다). T이 다형성 , 컴파일러는 런타임에 유형 ID 물건을 평가하는 데 필요한 경우

그러므로 나는 또한 어떤 종류의 T를 들어

+0

예, 나는 is_same에 대해 몰랐다. 그러나 이것이 내가 원하는 것이다. 감사! – cyril42e

2

is_same을 추천합니다. T가 다형 적이 아닌 경우 컴파일러는 컴파일 타임에 typeid 내용을 평가해야합니다. 그러나 C++ 초안 (n3000.pdf)에서 관련 참조를 찾을 수 없습니다.

사실, 내가 작업 한 프로젝트 중 하나에서이 트릭을 사용하여 클래스가 다형성인지 여부를 확인하는 데 사용되었습니다.

template <class T> 
bool isPolymorphic() { 
    bool answer=false; 
    T *t = new T(); 
    typeid(answer=true,*t); 
    delete t; 
    return answer; 
} 

나는 몇 달 전에 관련 질문 here을 물었다.

+1

좋습니다.하지만 형식 이름이 아닌 개체에 대해 typeid를 사용하고 있습니다. 유형이 다형성 인 경우에도 컴파일 타임에 유형 이름이 주어 졌으므로 완전히 알려지지 않았습니까? – cyril42e

+0

그냥 로컬 객체를 선언하는 대신에'new' /'delete'를 수행하는 것이 무엇 이었습니까? – AnT

+0

@AndreyT :'lvalue'를 산출하는 것은 typeid 연산자를 위해 할 것입니다. 나는 완성도를 위해 다른 스레드의 대답을 넣었습니다. – Abhay

관련 문제