Engineering/C++

C++에서 auto vs decltype vs typeid

luckydipper 2024. 6. 10. 13:01
반응형

C++를 하다 보면 타입이 맞지 않아 에러가 나는 경우가 많다. 이때마다 python의 type(class)이 부러워진다. 한편으론 생각 없이 auto와 decltype을 남발하면 되는 것이 아닌지 의구심이 든다. 하지만 C++의 장점은 이 타입을 강력하게 지켜준다는 것이다. 이 때문에 런타임에 발생할 에러를 미리 잡을 수 있고, 성능도 빨라진다.

해당 포스트의 목표는 C++의 타입을 알 수 있는 세가지 방법, auto, decltype, typeid를 비교하는 것이다.

1. auto와 decltype

이들은 C++11에 추가된 기능이며, 근본은 generic programming에 근간을 두고 있다. template과 원리가 똑같다. 즉, user가 준 type에 맞춰서 코드를 생성해 준다. generic programming을 이용하면, type promotion (int가 double과 계산되어 double이 output) 같은 것에서의 overhead를 줄일 수 있다. 즉 컴파일 타임에 auto와 decltpye에 들어갈 타입을 추론해 준다.

  • auto의 특징
    • 생성과 동시에 초기화해줘야 한다.
      auto a = 10; 
      // C++ 11에서는 tailing return type을 아래와 같이 표기했다. 
      template <typename U, typename T> 
      auto temp_foo(U a, T b) -> decltype(a+b){
      //즉, decltype으로 \
      } 
      // C++14부터는 return type을 auto로 쓰면 된다. 
      template <typename U, typename T> 
      auto temp_foo(U a, T b){ } 
      // C++14이더라도 return 값을 call by reference 까지 고려하게 하고 싶으면 // decltype(auto)를 활용하여 return한다.
    • {1,3,3,4,2}; 중괄호로 초기화될 때 std::initializer_list로 초기화한다.
  • dectype의 특징
    • decltype은 input 된 variable의 type을 추론한다.

2. typeid

  • C++98에 추가된 기능이다.
  • runtime에 어떤 type인지 확인할 수 있다.
  • 성능과 보안 때문에 사용이 꺼려진다.
#include <iostream>
#include <typeinfo>
#include <string>

class Base {  
public:  
virtual ~Base() = default;  
};

class Derived : public Base {};

int main() {  
int a = 10;  
double b = 3.14;  
std::string c = "Hello, World!";

std::cout << "Type of a: " << typeid(a).name() << std::endl;
std::cout << "Type of b: " << typeid(b).name() << std::endl;
std::cout << "Type of c: " << typeid(c).name() << std::endl;

Base* basePtr = new Base();
Base* derivedPtr = new Derived();

std::cout << "Type of *basePtr: " << typeid(*basePtr).name() << std::endl;
std::cout << "Type of *derivedPtr: " << typeid(*derivedPtr).name() << std::endl;

delete basePtr;
delete derivedPtr;

return 0;
}  
반응형