Nested vector<any> bug

Viewed 107

This code results in an error message:

libc++abi: terminating with uncaught exception of type std::bad_any_cast: bad any cast

vector<any> A = {vector<any>({1, 2})};
cout << any_cast<int>(any_cast<vector<any>>(A[0])[0]) << endl;

I am unable to debug this problem. Note that the following works and correctly outputs 1:

vector<any> A = {vector<int>({1, 2})};
cout << any_cast<vector<int>>(A[0])[0] << endl;

When I try to find the type of any_cast<vector>(A[0])[0] - which is obviously int - I get the same error message:

cout << any_cast<vector<any>>(A[0])[0].type().name() << endl;

libc++abi: terminating with uncaught exception of type std::bad_any_cast: bad any cast

1 Answers

It appears to me that your code snippet does not properly match the any_cast with the type that is being casted to. Not entirely sure, without a minimal, reproducible example, but that is what it appears.

You can use the any_cast in an inquiry fashion. Probably not great for performance, though, because it fails by throwing an exception which is then converted to the predicate returning false. For non-production code, should be fine.

Here's a vector<any> that contains one of: vector<any>, or int or string.

#include <any>
#include <iostream>
#include <string>
#include <vector>

using std::any;
using std::any_cast;
using std::bad_any_cast;
using std::cout;
using std::ostream;
using std::string;
using std::vector;

namespace {

bool is_vector_any(any const& x) {
    try {
        any_cast<vector<any>>(x);
        return true;
    } catch(bad_any_cast const&) {
    }

    return false;
}

bool is_int(any const& x) {
    try {
        any_cast<int>(x);
        return true;
    } catch(bad_any_cast const&) {
    }

    return false;
}

bool is_string(any const& x) {
    try {
        any_cast<string>(x);
        return true;
    } catch(bad_any_cast const&) {
    }

    return false;
}

static
auto operator<<(ostream& out, vector<any> const& v) -> ostream& {
    auto sep = string("");

    for (auto const& x : v) {
        if (is_vector_any(x)) {
            out << sep << "{ " << any_cast<vector<any>>(x) << " }";
        } else if (is_int(x)) {
            out << sep << any_cast<int>(x);
        } else if (is_string(x)) {
            out << sep << any_cast<string>(x);
        } else {
            out << sep << "?";
        }

        sep = " ";
    }

    if (sep == "") {
        out << "(empty)";
    }

    return out;
}

} // anon

int main() {
    vector<any> A = {vector<any>({1, 2})};
    A.push_back(vector<any>({string{"yes"}, string{"no"}, 3}));
    cout << "{ " << A << " }\n";
}
Related