C ++에서 변수의 유형을 어떻게 찾습니까?
C ++에서 변수의 유형을 어떻게 찾습니까?
답변:
typeid 연산자를 사용할 수 있습니다 .
#include <typeinfo>
...
cout << typeid(variable).name() << endl;
i
컴파일러에서 정수를 의미합니다. 반환 된 이름은 표준에 의해 지정되지 않습니다.
typeid
은 매우 축약되고 컴파일러에 따라 다르며 사람이 사용할 수 없습니다. gcc.gnu.org/onlinedocs/libstdc++/manual/ext_demangling.html 과 같은 코드에서 ,와 같은 명령 줄 유틸리티 c++filt
를 사용하거나 다양한 온라인 demangler를 사용하여 코드를 "demangle"할 수 있습니다 (실제 용어입니다!). demangler.com 과 같은 .
C ++와 Javascript의 주요 차이점은 C ++는 정적 유형 언어이고 wile javascript는 동적이라는 것입니다.
동적 유형 언어에서 변수는 모든 것을 포함 할 수 있으며 그 유형은 순간적으로 보유한 값에 의해 제공됩니다. 정적 유형 언어에서는 변수 유형이 선언되며 변경할 수 없습니다.
동적 디스패치 및 객체 구성 및 하위 유형 (상속 및 가상 함수)과 정적 디스패치 및 수퍼 타이핑 (템플릿 CRTP를 통해)이있을 수 있지만, 어떤 경우에도 변수 유형은 컴파일러에 알려야합니다.
그것이 무엇인지, 무엇이 될 수 있는지 모르는 위치에 있다면, 언어가 동적 유형 시스템을 가지고 있기 때문에 무언가를 설계했기 때문입니다.
그럴 경우 디자인을 다시 생각하는 것이 더 낫다면, 사용하는 언어로 자연스럽지 않은 땅으로 들어가기 때문입니다 (가장 애벌레가있는 고속도로 나 자동차로 물속에 들어가는 것과 비슷 함).
일반적으로 C ++에서 변수 유형을 찾는 것은 잘못된 질문입니다. 예를 들어 C 또는 Pascal과 같은 절차 언어에서 수행하는 경향이 있습니다.
유형에 따라 다른 동작을 코딩하려면 함수 오버로딩 및 객체 상속 에 대해 알아보십시오 . 이것은 C ++의 첫날에 즉각적인 의미가 없지만 계속 유지하십시오.
sizeof ()를 사용하는 것과 같은 방식으로 typeid () 사용에 대한 유효한 사용 사례가 있다고 생각합니다. 템플릿 함수의 경우 최대한의 기능과 유연성을 제공하기 위해 템플릿 변수를 기반으로하는 코드를 특수하게 처리해야합니다.
지원되는 각 유형에 대해 하나의 함수 인스턴스를 만드는 것은 다형성을 사용하는 것보다 훨씬 간결하고 유지 관리가 쉽습니다. 이 경우에도이 트릭을 사용하여 함수 본문을 한 번만 작성할 수 있습니다.
코드는 템플릿을 사용하기 때문에 아래의 switch 문은 하나의 코드 블록으로 정적으로 해석되어 모든 잘못된 경우 AFAIK를 최적화해야합니다.
T가 한 유형과 다른 유형 인 경우 변환을 처리해야 할 수있는이 예제를 고려하십시오. 하드웨어가 myClassA 또는 myClassB 유형을 사용하는 하드웨어에 액세스하기 위해 클래스 전문화에 사용합니다. 불일치시 데이터 변환에 시간을 투자해야합니다.
switch ((typeid(T)) {
case typeid(myClassA):
// handle that case
break;
case typeid(myClassB):
// handle that case
break;
case typeid(uint32_t):
// handle that case
break;
default:
// handle that case
}
typeid
정의에 따라 정적 컴파일 시간 검사가 될 수 없으므로 최적화가 용이하지 않습니다. For a template function, I need to special case the code based on the template variable
맞습니다. 정말로 원하는 것은 CRTP 관용구를 통한 정적 다형성입니다. 이것이 바로 그것이 달성 한 것입니다.
내 대답이 도움이 될지 모르겠습니다.
짧은 대답은 사용하기 위해 변수의 유형을 실제로 알 필요가 / 알고 싶지 않다는 것입니다.
정적 변수에 유형을 지정해야하는 경우 auto를 사용하면됩니다.
클래스 나 구조체에서 "auto"를 사용하려는보다 복잡한 경우에는 decltype과 함께 템플릿을 사용하는 것이 좋습니다.
예를 들어, 다른 사람의 라이브러리를 사용 중이고 "unknown_var"라는 변수가 있고 벡터 또는 구조체에 넣으려면 다음과 같이 할 수 있습니다.
template <typename T>
struct my_struct {
int some_field;
T my_data;
};
vector<decltype(unknown_var)> complex_vector;
vector<my_struct<decltype(unknown_var)> > simple_vector
도움이 되었기를 바랍니다.
편집 : 좋은 측정을 위해 여기에 내가 생각할 수있는 가장 복잡한 경우가 있습니다. 알 수없는 유형의 전역 변수가 있습니다. 이 경우 C ++ 14 및 템플릿 변수가 필요합니다.
이 같은:
template<typename T> vector<T> global_var;
void random_func (auto unknown_var) {
global_var<decltype(unknown_var)>.push_back(unknown_var);
}
여전히 약간 지루하지만 유형없는 언어에 도달 할 수있는 한 가깝습니다. 템플릿 변수를 참조 할 때마다 항상 템플릿 사양을 거기에 넣으십시오.
클래스와 알려진 유형을 비교해야하는 경우 예를 들면 다음과 같습니다.
class Example{};
...
Example eg = Example();
이 비교 라인을 사용할 수 있습니다.
bool isType = string( typeid(eg).name() ).find("Example") != string::npos;
typeid
이름에 문자열 유형이 포함되어 있는지 확인합니다 (typeid 이름에는 다른 데이터가 손상되어 있으므로 대신를 수행하는 s1.find(s2)
것이 가장 좋습니다 ==
).
typeid(x).name()
x가 변수 이름 인 곳으로 확실히 갈 수 있습니다 . 실제로 데이터 유형에 대한 const char 포인터를 반환합니다. 이제 다음 코드를보십시오.
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n = 36;
char c = 'A';
double d = 1.2;
if(*(typeid(n).name()) == 'i'){
cout << "I am an Integer variable" << endl;
}
if(*((char *) typeid(d).name()) == 'd'){
cout << "I am a Double variable" << endl;
}
if(*((char *) typeid(c).name()) == 'c'){
cout << "I am a Char variable" << endl;
}
return 0;
}
첫 번째와 두 번째가 모두 작동하는지 확인하십시오.
std::cout << "I'm a variable of type " << typeid(n).name()
. (아티팩트를 방지하기 위해 변경되었지만 다른 검사로 수정할 수 있습니다). 그럼에도 불구하고 절대적으로 비교를 원하면 훨씬 더 낫습니다typeid(n) == typeid(int)