这是二进制变体访问的主要用例。
这在一定程度上将运行时多态性转变为静态多态性(尽管内部仍在使用类型判别boost::variant
,但这不使用或不需要 RTTI)。
另请注意,您绝对不需要为所有组合添加单独的案例:我已经演示了使用模板行为实现的案例
- 参数具有相同的实际类型(“相同”)
- 不存在其他过载
我还展示了如何通过显示所采用的重载(接受 A、B、C、... 并结合 A 类型(或派生)的第二个参数来混合“经典”运行时多态性。Base, A
最后,请注意,这种方法还允许您重载右值、常量和波动性。
#include <iostream>
#include <boost/variant.hpp>
#include <string>
struct Base {};
struct A: Base {};
struct B: Base {};
struct C: Base {};
typedef boost::variant<A, B, C> MyType;
struct MyBehaviour : boost::static_visitor<std::string>
{
template <typename T>
std::string operator()(T const&, T const&) const { return "identical"; }
std::string operator()(A const&, B const&) const { return "A, B"; }
std::string operator()(A const&, C const&) const { return "A, C"; }
std::string operator()(Base const&, A const&) const { return "[ABC], A"; }
std::string operator()(Base const&, Base const&) const { return "Other"; }
};
int main()
{
MyBehaviour f;
MyType a = A{},
b = B{},
c = C{};
std::cout << boost::apply_visitor(f, a, b) << "\n";
std::cout << boost::apply_visitor(f, a, c) << "\n";
std::cout << boost::apply_visitor(f, a, a) << "\n";
std::cout << boost::apply_visitor(f, b, b) << "\n";
std::cout << boost::apply_visitor(f, c, c) << "\n";
std::cout << boost::apply_visitor(f, c, a) << "\n";
std::cout << boost::apply_visitor(f, c, b) << "\n";
}
在 Coliru 上看到它,输出:
A, B
A, C
identical
identical
identical
[ABC], A
Other