개요
- 복사 가능한 객체를 타입에 상관없이 담을 수 있는 클래스
- 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