2009-12-31 4 views
5

C++에서 런타임 정보로 유형을 판별 할 수 있는지 궁금합니다.C++에 대한 런타임 판별 유형

(1) 내 질문은 매우 일반적이지만, 단순, 나는 간단한 예제부터 시작됩니다 :

의 (a) "는 argv : 두 가지 질문이이 예를 들어

#include <stdio.h> 
#include <iostream> 
#include <cstring> 
using namespace std; 
int main(int argc, char * argv[]) 
{ 
if (strcmp(argv[1], "int")==0) 
{ 
    int t = 2; 
}else if (strcmp(argv[1], "float")==0) 
{ 
    float t = 2.2; 
} 
cout << t << endl; // error: ‘t’ was not declared in this scope 
return 0; 
} 

[1]에서 t "까지 잘못되었지만 C 문자열의 유형 정보 argv [1]을 실제 유형 키워드로 변환 할 수 있습니까? 따라서 우리는 if-else 절과 strcmp로 모든 유형을 검사 할 필요가 없습니다.

(b) if 절의 로컬 범위 내에서 정의 된 변수 t를 외부에서 여전히 유효하게 만드는 방법. 로컬 변수를 범위 외부로 "내보내는"방법은 무엇입니까?

(2) 일반적으로 위의 간단한 예제와 관련이 없지만 런타임에서 유형을 결정하는 일반적인 방법은 무엇입니까? 어떤 방법이있을 수 있습니다.

(a) 하나의 유형에서 정의 된 변수의 처리를 동일한 범위 안에 정의 할 수 있습니다. 예 :

#include <stdio.h> 
#include <iostream> 
#include <cstring> 
using namespace std; 
int main(int argc, char * argv[]) 
{ 
if (strcmp(argv[1], "int")==0) 
{ 
    int t = 2; 
    cout << t << endl; 
}else if (strcmp(argv[1], "float")==0) 
{ 
    float t = 2.2; 
    cout << t << endl; 
} 
return 0; 
} 

아마도 템플릿 함수를 사용하여 다양한 유형의 공통 코드를 재사용 할 수 있습니다.

(b) 또는 추상 클래스 유형 및 다형성을 사용하여 정의를 간접적으로 내보낼 수는 있지만 정확히 어떻게 전달되는지는 확실하지 않습니다.

귀하의 조언에 감사드립니다.

답변

7

1a : 아니요, 유형은 C++의 객체 또는 값이 아닙니다 (예 : Python에서와 같이). 그러나 argv [1]의 값에 의해 선택된 다양한 값을 사용할 수 있습니다.

1b : 죄송합니다. 그냥 할 수 없습니다.

2 : dynamic_cast 및 typeid (두 연산자)는 현재 언어가 검색어 유형에 제공하는 유일한 도구입니다 (대부분의 언어는 거의 없지만 전용 도구가 있으므로 검색어 유형에만 사용). 상황에 따라 종종 낙심하기도합니다 (다른 언어들 중에서도 예외가 아닙니다).

2a : 그렇습니다. 간단하고 명백하며 여기서 작동합니다. — 다른 용도는 사용할 필요가 없지만 예제 코드처럼 다른 해결책이 필요하다고 가정 해 봅시다. 올바른 유형으로 인스턴스화 된 함수 템플리트를 호출 할 수 있지만 나머지 2a와 거의 동일하므로이 부분으로 넘어 가지 않습니다.

2B : 예이 편리 그냥 때문에, 서브 클래스 템플릿을 사용하여 :

struct Base { 
    virtual ~Base() {} 
    friend std::ostream& operator<<(std::ostream& s, Base const& v) { 
    v._print(s); 
    return s; 
    } 
private: 
    virtual void _print(std::ostream&) const = 0; 
}; 

template<class T> 
struct Value : Base { 
    T data; 
    explicit 
    Value(T const& data) : data(data) {} 
private: 
    virtual void _print(std::ostream& s) const { 
    s << data; 
    } 
}; 

사용이 하나 개의 유형으로 두 가지를 병합하기 시작하고,

int main(int argc, char** argv) { 
    using namespace std; 
    auto_ptr<Base> p; 
    string const type = argc > 1 ? argv[1] : "int"; 
    if (type == "int") { 
    p.reset(new Value<int>(2)); 
    } 
    else if (type == "float") { 
    p.reset(new Value<double>(2.2)); 
    } 
    cout << *p << '\n'; 
    return 0; 
} 

둘 다 제시 같은 인터페이스,베이스, 여기.그러나 이것은 모든 솔루션에 적합하지 않으며 boost.variant과 같은 변형이 더 좋을 수 있습니다. 특히 필요한 다양한 유형이 적고 사전에 잘 알려져있을 때 더욱 좋습니다.

+0

+1 다형성 해결책을 게시하려고했습니다. boost.variant를 사용하면 모든 작업의 ​​유형을 확인해야하기 때문에 boost.variant보다 훨씬 의미가 있습니다. –

5

다른 유형의 값을 저장할 수있는 클래스가 필요합니다. 노조에서 짧은, Boost's variant class 적절한 선택이 될 것입니다.

+0

부스트를 사용하지 않는 경우? – Tim

+0

내가 언급했듯이, 노동 조합. –

2

체크 아웃 Boost.Variant

+1

원본 질문에 부스트 (Boost) 사용을 제안하는 것은 없습니다. 왜 그는 한 기능에 대해 완전히 새로운 프레임 작업을 포함해야합니까? 미안하지만 도움이되는 것으로 보지 않습니다. –

+3

@druciferre : 질문은 C++에서 무언가를하는 방법을 묻습니다. 많은 경험 많은 C++ 개발자들은 부스트에 대해 들어 보지 못했을 지 모르지만, 있어야합니다. 질문에는 네임 스페이스 std, 표준 템플릿 라이브러리에 대한 참조가 이미 포함되어 있습니다. Boost를 STL로 사용할 수있는 것으로 간주 할 수 있습니다. 이제 Boost에는 많은 라이브러리가 있으므로 특정 문제에 대해서만 의미있는 라이브러리 만 존재하게됩니다. – jmc

관련 문제