Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

cout vector of std::any [duplicate]

Tags:

c++

c++17

I have a std::vector of std::any, all of which can be printed via << (e.g., only ints and floats). I'd love to have something like

#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;
}

but that doesn't work since std::any doesn't know <<:

error: no match for ‘operator<<’

The only workaround I've come up with so far is to explicitly cast the vector items into whatever data type might be in it, e.g.,

#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;
}

This is (perhaps unnecessarily) verbose and also rather inflexible since once has to know all data types that might occur in the vector.

Is there a variant of vector<any> printing without those disadvantages?

like image 305
Nico Schlömer Avatar asked Jul 01 '17 18:07

Nico Schlömer


People also ask

How do you check if there are duplicates in a vector C++?

1. Using std::set_difference. To find duplicates present in a vector, we can find the set difference between the original elements and the distinct elements.

Can std::vector have duplicates?

Yes, but sorting a vector modifies the original content.


Video Answer


1 Answers

You are using the wrong type. Since "only ints and floats" are stored here, then what you clearly want is a std::variant<int, float>, not an any. You can then print such a vector easily enough:

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

any is primarily for communication between two locations through an intermediary, where the start point and end point both know the exact type to be used, but the intermediary does not. Think of a signaling system; the sender and receiver of the signal know what type to use, but the signaling system doesn't care.

Applying an operation over a small, fixed range of types is more variant territory. Applying an operation over an unbounded range of types is some form of genuine polymorphism: either compile-time (templates) or runtime (virtual functions).

like image 97
Nicol Bolas Avatar answered Sep 29 '22 10:09

Nicol Bolas