我正在尝试使用类型擦除概念。基于对象类型,我想将其转换为具体类型。我试图这样做,如下图所示,但它没有工作。它打印一些数字而不是11。我做错了什么?
尝试
std::vector<Object> v;
v.emplace_back(Object(Obj1(11)));
v.emplace_back(Object(Obj2("test")));
Object o1 = v[0];
auto c1 = static_cast<Object::Concept*>(o1.object.get());
auto m1 = static_cast<Object::Model<Obj1>*>(c1);
std::cout << m1->object.i;
代码
enum class ObjType { ObjType1, ObjType2 };
struct Object
{
template<typename T>
Object(T&& obj): object(std::make_shared<Model<T>>(std::forward<T>(obj))) {}
ObjType getType() const { return object->getType(); }
struct Concept
{
virtual ~Concept() {}
virtual ObjType getType() const = 0;
};
template<typename T>
struct Model : Concept
{
Model(const T& t) : object(t) {}
T object;
ObjType getType() const override { return object.getType(); }
};
std::shared_ptr<Concept> object;
};
struct Obj1
{
int i;
Obj1(int i) : i(i) {}
ObjType getType() const { return ObjType::ObjType1; }
};
struct Obj2
{
std::string s;
Obj2(std::string s) : s(s) {}
ObjType getType() const { return ObjType::ObjType2; }
};
1条答案
按热度按时间rjee0c151#
将使用模板化构造函数,而不是要在中使用的默认复制构造函数
这里使用的构造函数实际上是
Object::Object<Object&>
。为了避免这种情况,如果参数类型是
Object
(或任何对Object
的引用),您可以简单地不使模板化构造函数适用:当然,如果您实际上想使用
Object::Model<Object>
,这可能是一个问题;如果您打算这样做,我建议在名称空间范围内添加一个make_object
函数,而不是通过构造函数实现对象创建。附加说明:很有可能为构造函数推导出的模板参数是
Obj1&
或Obj1 const&
(或Obj2
的等价物),因此在选择Model
类型时,您可能希望删除引用,并可能删除const
:或者是
**编辑:**对于C++14概念不能使用,
std::remove_cvref_t
也不可用,因此需要使用SFINAE和std::remove_const_t<std::remove_reference_t<...>>
: