C++中std::variant与std::shared_ptr配合使用报错问题排查
问题与解答:std::variant使用错误及修复
编译错误信息
In static member function ‘static std::shared_ptr<std::variant<MyClass<InputClass1>, MyClass<InputClass2> > > MyCreatorClass::create()’: main.cpp:34:57: error: could not convert ‘std::make_shared(_Args&& ...) [with _Tp = MyClass; _Args = {}]()’ from ‘shared_ptr>’ to ‘shared_ptr, MyClass >>’
问题代码
#include <iostream> #include <variant> #include <memory> using namespace std; struct InputClass1{ static std::string MyName(){ return "InputClass1"; } }; struct InputClass2{ static std::string MyName(){ return "InputClass2"; } }; template<class InputClass> class MyClass{ public: MyClass(){ std::cout<<InputClass::MyName(); } }; class MyCreatorClass{ using VariantType = std::variant<MyClass<InputClass1>, MyClass<InputClass2>>; public: static std::shared_ptr<VariantType> create(){ return std::make_shared<MyClass<InputClass2>>(); } // Am I using the variant the right way here? }; int main() { cout<<"Hello World"; MyCreatorClass::create(); return 0; }
用户问题
是否正确使用了std::variant?该如何解决这个编译错误?
错误原因与修复方案
错误本质
create函数声明返回的是std::shared_ptr<VariantType>(即shared_ptr<variant<MyClass<InputClass1>, MyClass<InputClass2>>>),但实际返回的是shared_ptr<MyClass<InputClass2>>,两个类型完全不兼容,编译器无法自动转换,因此抛出错误。
修复方法
你需要将MyClass<InputClass2>的实例放入std::variant容器中,再用make_shared包装整个variant对象,而不是直接包装MyClass实例。
方案1:直接构造variant并包装
修改后的create函数:
static std::shared_ptr<VariantType> create(){ return std::make_shared<VariantType>(MyClass<InputClass2>()); }
方案2:使用std::in_place_type高效构造
这种写法可以直接在variant内部构造目标类型,避免额外的拷贝/移动操作:
static std::shared_ptr<VariantType> create(){ return std::make_shared<VariantType>(std::in_place_type<MyClass<InputClass2>>); }
核心说明
std::variant是一个可存储多种类型中某一种的容器,必须把具体类型的实例放进这个容器后,再对整个容器进行智能指针包装,不能直接将具体类型的智能指针当作variant的智能指针返回。
内容的提问来源于stack exchange,提问作者user1008636
相关产品推荐
相关产品推荐

