在我的 C++ 库中,我有一个类型 boost::variant<A,B>
许多算法将这种类型作为输入。我没有成员函数,而是这种类型的全局函数,比如 void f( boost::variant<A,B>& var )
.我知道这也可以用模板来实现,但这不适合我的设计。
我非常喜欢这种编程风格:
boost::variant<A, B> v;
f( v );
但是这个库的一些用户不习惯,而且由于 Boost.Variant 概念被类型定义隐藏了,他们感觉像调用 v.f()
.
为了实现这一点,我可以想到两种可能性:1) 从 boost::variant
覆盖和 2) 重新实现 boost::variant
并添加我自己的成员函数。我不确定这些想法是否好。你能给我一些帮助吗?还有其他可能性吗?
最佳答案
另一种可能性:使用聚合。这样您就不会直接将 boost.variant 公开给库的用户,从而为您方式提供更多的自由来进行 future 的改进,并且可能会大大简化一些调试任务。
一般建议: 聚合不如继承紧密耦合,因此默认情况下更好,除非您知道一个用例,在该用例中您明确希望将对象实例传递给仅采用变体的现有函数。甚至在设计基类时也应考虑到继承。
您的问题的聚合示例: 据我了解,免费功能已经存在,并且有一个变体。只需定义一个具有变体唯一数据成员的类,并提供公共(public)成员函数,这些函数除了调用具有成员变体的已经存在的自由函数外什么都不做,比如
class variant_wrapper {
boost::variant<A,B> m_variant;
public:
variant_wrapper(...) : m_variant(...) {} // whatever c_tor you need.
void f() { f(m_variant); }
};
使用这种方法,您可以抽象出您正在使用 boost.variant 进行实现的事实(您已经通过 typedef 为库的用户完成了),让您可以自由地稍后更改它(用于优化或功能扩展或无论如何),您可以决定使值不可变,使用更简单的方法来调试对算法的访问等。
聚合的缺点是你不能只将包装器传递给 static_visitor,但由于你的用户不知道有一个变体,而你知道简单地传递成员变量,我不认为这是一个大问题在这里。
最后的咆哮: C++ 不是 Java。您需要修复库的用户...
您想要的是 C# 扩展方法; C++中不存在这样的东西。但是,我不会重新实现/实现复制 boost.variant(维护负担),并且我不会继承它。尽可能使用聚合。
关于c++ - 将成员函数添加到 Boost.Variant,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2361717/