cout矢量std :: any

时间:2017-07-01 18:27:29

标签: c++ c++17

我有std::vector std::any,所有这些都可以通过<<打印(例如,只有整数和浮点数)。我喜欢有像

这样的东西
#include <experimental/any>
#include <iostream>
#include <vector>

int main() {
  std::vector<std::experimental::any> v;

  v.push_back(1);
  v.push_back(3.14);

  for (const auto& a: v) {
    std::cout << a << std::endl;
  }

  return 0;
}

但由于std::any不知道<<

,因此无效
error: no match for ‘operator<<’

到目前为止,我提出的唯一解决方法是将向量项明确地转换为其中可能存在的任何数据类型,例如,

#include <experimental/any>
#include <iostream>
#include <vector>

int main() {
  std::vector<std::experimental::any> v;

  v.push_back(1);
  v.push_back(3.14);

  for (const auto& a: v) {
    try {
        std::cout << std::experimental::any_cast<int>(a) << std::endl;
    } catch (const std::experimental::fundamentals_v1::bad_any_cast&)
    {}

    try {
        std::cout << std::experimental::any_cast<double>(a) << std::endl;
    } catch (const std::experimental::fundamentals_v1::bad_any_cast&)
    {}
  }

  return 0;
}

这可能(可能是不必要的)冗长而且相当不灵活,因为曾经必须知道向量中可能出现的所有数据类型。

是否有vector<any>打印的变体没有这些缺点?

1 个答案:

答案 0 :(得分:8)

您使用的是错误的类型。由于此处仅存储“仅内联和浮点数”,因此您明确需要的是std::variant<int, float>,而不是any。然后,您可以轻松地打印这样的vector

for (const auto& a: v) {
  std::visit([](const auto &val) {std::cout << val << std::endl;}, a);
}

any主要用于通过中介在两个位置之间进行通信,其中起点和终点都知道要使用的确切类型,但中间人不知道。想想信号系统;信号的发送者和接收者知道使用什么类型,但信号系统并不关心。

在较小的固定范围的类型上应用操作的区域更多variant。在无限范围的类型上应用操作是某种形式的真正多态:编译时(模板)或运行时(virtual函数)。