[C++] any
Updated:
개요
- 복사 가능한 객체를 타입에 상관없이 담을 수 있는 클래스
- typesafe void*라고 표현하기도 함
- 값을 변경하는 경우 기존 객체의 소멸을 보장
- any_cast 함수로 접근
- 복사한 값을 반환하고 기존 객체 소멸
- 타입이 다를 경우 bad_any_cast 예외 발생
- any 객체가 포인터라면 접근이 가능한 경우엔 해당 포인터, 불가능하면 nullptr 반환
- void*, reinterpret_cast는 typesafe 하지도 수명관리도 하지 않음
- shared_ptr은 수명관리는 하지만 typesafe하지 않음
- 저장할 타입을 알 수 있다면 optional, 타입들을 컴파일 시점에 알 수 있다면 variant를 사용하는 것이 좋음
- any는 유연함을 위해 상대적으로 성능 하락이 존재
예제
- 코드
#include <any> #include <iostream> #include <string> using namespace std; class Test { public: Test() { cout << "Test()" << endl; } Test(Test &&t) { cout << "Test(Test &&t)" << endl; } Test(const Test &t) { cout << "Test(const Test &t)" << endl; } ~Test() { cout << "~Test()" << endl; } void func() { cout << "func()" << endl; } }; int main() { any a = make_any<Test>(); cout << a.has_value() << endl; cout << a.type().name() << endl; cout << "------ 1" << endl; any_cast<Test>(a).func(); cout << "------ 2" << endl; cout << "------ 3" << endl; any_cast<Test &>(a).func(); cout << "------ 4" << endl; cout << "------ 5" << endl; a = 1; cout << "------ 6" << endl; cout << a.type().name() << endl; cout << any_cast<int>(a) << endl; try { cout << any_cast<string>(a) << endl; } catch (bad_any_cast &e) { cout << e.what() << endl; } cout << "------ 7" << endl; cout << any_cast<int>(&a) << endl; cout << *any_cast<int>(&a) << endl; cout << any_cast<string>(&a) << endl; cout << "------ 8" << endl; a.reset(); return 0; }
- 실행 결과
Test() 1 4Test ------ 1 Test(const Test &t) func() ~Test() ------ 2 ------ 3 func() ------ 4 ------ 5 ~Test() ------ 6 i 1 bad any_cast ------ 7 0x7fff76a0fb28 1 0 ------ 8