c++ - std::any 由 std::exception_ptr

标签 c++ c++11 variant

可能我不是第一个发现 std::exception_ptr 可用于实现 any 类型(性能考虑被搁置)的人,因为它是可能是 C++ 中唯一可以容纳任何东西的类型。然而,谷歌搜索并没有在这方面带来任何结果。

有人知道以下方法是否已在任何地方使用过吗?

#include <exception>
#include <iostream>

struct WrongTypeError : std::exception { };

class Any {
public:
   template <class T>
   void set (T t) {
      try { throw t; }
      catch (...) { m_contained = std::current_exception(); }
   }

   template <class T>
   T const & get () {
      try { std::rethrow_exception (m_contained); }
      catch (T const & t) { return t; }
      catch (...) { throw WrongTypeError {}; }
   }

private:
   std::exception_ptr m_contained = nullptr;
};

int main () {
    auto a = Any {};
    a.set (7);
    std::cout << a.get<int> () << std::endl;

    a.set (std::string {"Wonderful weather today"});
    std::cout <<  a.get<std::string> () << std::endl;
    return 0;
}

最佳答案

as it is probably the only type in C++ that can hold anything.

恐怕不是这样的。 boost::any 可以容纳任何类型,甚至可以正确地复制(假设该类型是可复制的)它。它是(广义上)使用基类和模板化子类实现的:

class any_base {
  ...
}

template <class T>
class any_holder : public any_base
{
 private:
  T m_data;
}

从这里你可以想象你可以将任何类型填充到一个 any_holder 中(使用正确的接口(interface)),然后你可以通过指向 any_base 的指针来持有一个 any_holder。这种技术是一种类型删除;一旦我们有了一个 any_base 指针,我们就持有一个对象,但对类型一无所知。你可以说这是完全类型删除,比如 std::function 提供了部分类型删除(并且可能在幕后使用类似的技术,我不确定我的头脑)。

boost::any 提供额外的接口(interface)来支持它持有任何类型的用法,并且它可能提供更好的性能,因为抛出异常非常慢。另外,正如我之前提到的,它正确地复制了底层对象,这非常棒。 exception_ptr 是一个共享所有权指针,所以我相信它会生成浅拷贝。

提升任何网站:http://www.boost.org/doc/libs/1_59_0/doc/html/any.html

我认为它正在考虑用于标准:http://en.cppreference.com/w/cpp/experimental/any

看起来实现类似于 boost 但增加了一个小对象优化。

exception_ptr 据我所知是一个非常奇怪的野兽,我以前遇到过它并用谷歌搜索它,但令人惊讶的是,那里的信息很少。但是我很确定它很神奇,即它不能在用户空间中实现。我这样说是因为当你抛出它时,该类型似乎神奇地取消了自身,这通常是不可能的。

关于c++ - std::any 由 std::exception_ptr,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34391357/

相关文章:

c++ - 存在用户定义的移动构造函数/赋值时的隐式复制构造函数

c++ - 更改类型后丢失对 std::variant 对象的引用

arrays - 作为类属性的变体类型的 VBA 数组

c# - 如何在 CLR/托管 C++ 中实现变体类型?

c++ - 成员函数指针和继承

c++ - 具有细粒度锁的线程安全链表

c++ - 多线程中是否需要原子类型? (OS X, clang, c++11)

c++ - 宏定义中双重否定的目的是什么,比如 (!!(expr))?

c++ - OpenCV c++ 断言在 cv::_InputArray::getMat 中失败 <i < 0>

c++ - 为什么默认构造函数不适用于 `vector::emplace_back`