作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个基类Object
:
struct Object{
};
n
(在这种情况下为2)从该类继承的类
struct Integer : public Object{
int i_;
Integer(int i) : i_{i}{}
}
struct Float : public Object{
float f_;
Float(float f) : f_{f}{}
}
std::vector<Object*> object_list{new Integer(1), new Float(2.1), new Integer(3), new Float(4.2)};
Integer* add(Integer* i, Integer* j);
Float* add(Integer* i, Float* f);
Float* add(Float* f, Float* g);
Float* add(Float* f, Integer* i);
Object
动态转换为所有可用类型-两次,如果我有足够的子类,这似乎是一场灾难。
f(Object* a, Object* b)
最佳答案
using Object = std::variant<Float, Integer>;
std::vector<Object>
并在其中存储
Float
和
Integer
。
struct Integer {
int val = 0;
friend std::ostream& operator<<( std::ostream& os, Integer const& obj ) {
return os << obj.val;
}
};
struct Float {
double val = 0.;
friend std::ostream& operator<<( std::ostream& os, Float const& obj ) {
return os << obj.val;
}
};
using Object = std::variant<Integer, Float>;
std::ostream& operator<<( std::ostream& os, Object const& obj ) {
// note: if the type in Object doesn't have a << overload,
// this will recurse and segfault.
std::visit( [&]( auto const& e ){ os << e; }, obj );
return os;
}
Integer add_impl(Integer const& i, Integer const& j) { return {i.val + j.val}; }
Float add_impl(Integer const& i, Float const& j) { return {i.val + j.val}; }
Float add_impl(Float const& i, Float const& j) { return {i.val + j.val}; }
Float add_impl(Float const& i, Integer const& j) { return {i.val + j.val}; }
Object add( Object const& lhs, Object const& rhs ) {
return std::visit( []( auto& lhs, auto& rhs )->Object { return {add_impl( lhs, rhs )}; }, lhs, rhs );
}
Object a = Integer{7};
Object b = Float{3.14};
Object c = Integer{-100};
Object d = Float{0.0};
std::cout << add( a, b ) << "," << add( b, c ) << "," << add( c, d ) << "," << add( add(a, b), add( c, d ) ) << "\n";
add
重载。
Object
,但在运行时将包含
Float
或
Integer
。
Object
的定义处。这些对象不必是相关类型。
add_impl
中的类型的 namespace 中而不是在中心位置扩展
Object
。 ADL将用于查找过载集。
operator+
instead of add
。
// note: if the type in Object doesn't have a << overload,
// this will recurse and segfault.
namespace ObjectOnly {
struct Object;
struct Object:std::variant<Integer, Float> {
using std::variant<Integer, Float>::variant;
std::variant<Integer, Float> const& base() const& { return *this; }
std::variant<Integer, Float> & base()& { return *this; }
std::variant<Integer, Float> const&& base() const&& { return std::move(*this); }
std::variant<Integer, Float> && base()&& { return std::move(*this); }
};
Object add_impl( Object const& lhs, Object const& rhs ) {
return std::visit( [](auto& lhs, auto& rhs)->Object { return {lhs+rhs}; }, lhs.base(), rhs.base() );
}
Object operator+( Object const& lhs, Object const& rhs ) {
return add_impl( lhs, rhs );
}
std::ostream& stream_impl( std::ostream& os, Object const& obj ) {
std::visit( [&]( auto const& e ){ os << e; }, obj.base() );
return os;
}
std::ostream& operator<<( std::ostream& os, Object const& obj ) {
return stream_impl( os, obj );
}
}
add_impl
看到
ObjectOnly::operator+
。仍然可以在与
operator+
或
Float
相同的命名空间中看到
Integer
。
Integer
编辑为不支持
<<
,则会得到编译时错误,而不是运行时错误。
关于c++ - 如何在基类指针 vector 的元素上应用重载的多态函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60060462/
我是一名优秀的程序员,十分优秀!