I am trying to experiment with std::variant. I am storing an std::variant as a member of a class. In the below code, things work fine if the variant is stored by value, but does not work (for the vector case, and for custom objects too) if the variant is stored by reference. Why is that?
#include <variant>
#include <vector>
#include <iostream>
template<typename T>
using VectorOrSimple = std::variant<T, std::vector<T>>;
struct Print {
void operator()(int v) { std::cout << "type = int, value = " << v << "\n"; }
void operator()(std::vector<int> v) const { std::cout << "type = vector<int>, size = " << v.size() << "\n"; }
};
class A {
public:
explicit A(const VectorOrSimple<int>& arg) : member(arg) {
print();
}
inline void print() const {
visit(Print{}, member);
}
private:
const VectorOrSimple<int> member; // const VectorOrSimple<int>& member; => does not work
};
int main() {
int simple = 1;
A a1(simple);
a1.print();
std::vector<int> vector(3, 1);
A a2(vector);
a2.print();
}
See http://melpon.org/wandbox/permlink/vhnkAnZhqgoYxU1H for a working version, and http://melpon.org/wandbox/permlink/T5RCx0ImTLi4gk5e for a crashing version with error : "terminate called after throwing an instance of 'std::bad_variant_access' what(): Unexpected index"
Strangely, when writing a boost::variant version of the code with the member stored as a reference, it works as expected (prints vector size = 3 twice) with gcc7.0 (see here http://melpon.org/wandbox/permlink/eW3Bs1InG383vp6M) and does not work (prints vector size = 3 in constructor and then vector size = 0 on the subsequent print() call, but no crash) with clang 4.0 (see here http://melpon.org/wandbox/permlink/2GRf2y8RproD7XDM).
This is quite confusing. Can someone explain what is going on? Thanks.