오랜만에 C++ : 같은 구조, 다른 데이터 다루기

주싱·2024년 4월 20일
0

개발일기

목록 보기
17/27

C++ 이라는 언어를 오랜만에 다시 접한다. 2024년에 접한 C++은 내가 10여년 전 접하던 것과는 많이 다른 느낌이 든다. 언어적으로 많은 부분 발전한 것 같다. 오늘은 객체지향의 다형성으로 해결할 수 없을 것 같은 다소 어려운 문제를 만났다. 코드가 동일한 구조로 동작하지만 완전히 다른 데이터를 사용하는 모듈들의 설계 문제이다. 데이터 구조가 완전히 다르니 상위 클래스를 정의해 사용할 수 없다. Java 언어에서는 이런 경우 모든 클래스의 상위 클래스인 Object 클래스를 사용하곤 했는데 C++에서는 그런게 없단다. C언어로 프로그래밍을 할 때 어떻게 했지 생각해 보니 union 타입을 사용했던 기억이 난다. 그래서 ChatGPT에서 C++에는 union 같은 기능을 제공하는 것이 없냐고 물으니 C++ 17 부터 variant 라는 클래스를 지원한다고 소개해 준다. 와! 내가 딱 원하던 것이다. 타입 안정성도 가져가면서 완전히 다른 데이터 타입을 하나의 클래스로 캡슐화해서 다룰 수 있다. 이런 배움을 얻는 일은 즐겁다. 오늘 프로젝트 주간 회의에서도 의미 있는 논의가 오갔다. 리스크가 큰 이슈가 하나있었는데 아직 성공을 바라보는 시점은 아니지만 긍정적인 방향을 확인한 것 같다. 퇴근 길 오랜만에 마음이 무척 가볍다. 아래는 variant 클래스를 사용하는 예제코드이다.

#include <cassert>
#include <iostream>
#include <string>
#include <variant>
 
int main()
{
    std::variant<int, float> v, w;
    v = 42; // v contains int
    int i = std::get<int>(v);
    assert(42 == i); // succeeds
    w = std::get<int>(v);
    w = std::get<0>(v); // same effect as the previous line
    w = v; // same effect as the previous line
 
//  std::get<double>(v); // error: no double in [int, float]
//  std::get<3>(v);      // error: valid index values are 0 and 1
 
    try
    {
        std::get<float>(w); // w contains int, not float: will throw
    }
    catch (const std::bad_variant_access& ex)
    {
        std::cout << ex.what() << '\n';
    }
 
    using namespace std::literals;
 
    std::variant<std::string> x("abc");
    // converting constructors work when unambiguous
    x = "def"; // converting assignment also works when unambiguous
 
    std::variant<std::string, void const*> y("abc");
    // casts to void const * when passed a char const *
    assert(std::holds_alternative<void const*>(y)); // succeeds
    y = "xyz"s;
    assert(std::holds_alternative<std::string>(y)); // succeeds
}

출처 : https://en.cppreference.com/w/cpp/utility/variant

profile
소프트웨어 엔지니어, 일상

0개의 댓글