【问题标题】:Cast boost::any instance to its real type将 boost::any 实例转换为其真实类型
【发布时间】:2014-10-09 00:05:49
【问题描述】:

我最近开始使用Boost C++ 库,我正在测试可以保存任何数据类型的any 类。实际上,我正在尝试定义operator<< 以轻松打印any 类型的任何变量的内容(当然,内容的类也应该定义operator<<)。 我只从样本类型开始(intdouble ...),因为它们默认显示。到现在为止,我有这个代码:

#include <boost/any.hpp>
#include <iostream>
#include <string>
using namespace std;
using namespace boost;

ostream& operator<<(ostream& out, any& a){
    if(a.type() == typeid(int))
        out << any_cast<int>(a);
    else if(a.type() == typeid(double))
        out << any_cast<double>(a);
    // else ...
    // But what about other types/classes ?!
}

int main(){
    any a = 5;
    cout << a << endl;
}

所以这里的问题是我必须枚举所有可能的类型。有没有办法将变量转换为具有 type_infoparticular typeparticular type

【问题讨论】:

  • 你不能枚举“所有可能的类型”。该类型称为 any,而不是 every
  • 也许您可以使用Boost type erasure 来满足更具体的类型擦除需求。就目前而言,这个问题令人困惑,因为标题是关于铸造的(这可能是错误的或不明智的),而正文是关于格式的,这是一个易于理解且完全不同的问题。
  • 我从未使用过boost::any,而且我写了一些非常奇怪的代码。你也不需要使用它。它的用途难以置信地很少。
  • @webNeat:这听起来像是一个经典的 X-Y 问题。
  • @BryanChen:您可以在删除operator&lt;&lt; 的同时boost::any 删除数据:coliru.stacked-crooked.com/a/de70c25df7302c7f,但这很 hack。

标签: c++ boost casting boost-any


【解决方案1】:

Boost.Any any

使用boost::any,您不能这样做,因为其他人已经在 cmets 中指出。那是因为boost::any 忘记了它存储的值类型的所有内容,并要求您知道存在的类型。虽然您无法枚举所有可能的类型。

解决方案是更改boost::any,使其忘记存储的值类型的所有内容除了如何将其流出。 Mooing Duck 在 cmets 中提供了一种解决方案。另一种方法是编写一个新版本的boost::any,但扩展其内部以支持流操作。

Boost.Spirit hold_any

Boost.Spirit 已经在 &lt;boost/spirit/home/support/detail/hold_any.hpp&gt; 中提供了类似的功能。

Boost.TypeErasure any

然而,更好的方法是使用 Boost.TypeErasureany,正如 Kerrek SB 在他的评论中提到的那样。

您的例子(使用&lt;&lt;)如下所示:

#include <boost/type_erasure/any.hpp>
#include <boost/type_erasure/operators.hpp>
#include <iostream>
#include <string>

int main() {
    typedef
        boost::type_erasure::any<
            boost::mpl::vector<
                boost::type_erasure::destructible<>,
                boost::type_erasure::ostreamable<>,
                boost::type_erasure::relaxed
            >
        > my_any_type;

    my_any_type my_any;

    my_any = 5;
    std::cout << my_any << std::endl;
    my_any = 5.4;
    std::cout << my_any << std::endl;
    my_any = std::string("text");
    std::cout << my_any << std::endl;
}

【讨论】:

    猜你喜欢
    • 2023-04-10
    • 1970-01-01
    • 2011-05-07
    • 1970-01-01
    • 1970-01-01
    • 2015-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多