gpt4 book ai didi

c++ - boost::变体和多态性

转载 作者:可可西里 更新时间:2023-11-01 18:25:25 26 4
gpt4 key购买 nike

如果我将 orignally 指针指向派生类,我想从 boost 变体获取指向基类的指针。有什么办法可以做到这一点。以下代码不起作用。

class A{ public: virtual ~A(){}}; class B : public A{};
typedef boost::variant<A*,B*> MyVar;
MyVar var = new B;
A* a = boost::get<A*> (var); // the following line throws exception

也许有人知道如何编写我自己的 get 函数,该函数将测试请求的类型是否是变体中存储类型的基类,然后进行适当的转换

最佳答案

您可以使用模板化 operator() 编写自己的访客如下所示:

LIVE DEMO

#include <iostream>
#include <boost/variant.hpp>
#include <type_traits>

struct A { virtual ~A() {} virtual void foo() {} };
struct B : A { virtual void foo() { std::cout << "B::foo()" << std::endl; } };

template <typename T>
struct visitor : boost::static_visitor<T>
{
private:
using Base = typename std::remove_pointer<
typename std::remove_cv<
typename std::remove_reference<T>::type
>::type
>::type;

template <typename U>
T get(U& u, std::true_type) const
{
return u;
}

template <typename U>
T get(U& u, std::false_type) const
{
throw boost::bad_get{};
}

public:
template <typename U>
T operator()(U& u) const
{
using Derived = typename std::remove_pointer<
typename std::remove_cv<
typename std::remove_reference<U>::type
>::type
>::type;

using tag = std::integral_constant<bool
, (std::is_base_of<Base, Derived>::value
|| std::is_same<Base, Derived>::value)
&& std::is_convertible<U, T>::value>;

return get(u, tag{});
}
};

template <typename T, typename... Args>
T my_get(boost::variant<Args...>& var)
{
return boost::apply_visitor(visitor<T>{}, var);
}

int main()
{
boost::variant<A*,B*> var = new B;

A* a = my_get<A*>(var); // works!
a->foo();

B* b = my_get<B*>(var); // works!
b->foo();
}

输出:

B::foo()
B::foo()

问答部分:

This solution is weird!

不,不是。这正是 Boost.Variant 中访问者类的用途。 Boost.Variant 的最新版本中已经存在类似的解决方案,即 boost::polymorphic_get<T> .遗憾的是,它是为其他目的而设计的,不能在这里使用。

关于c++ - boost::变体和多态性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25821414/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com