mapbox/variant

Bug leads to crash program when using .set<T>() and then apply_visitor()

Opened this issue · 1 comments

#include
#include <mapbox/variant.hpp>
#include <unordered_map>
using namespace std;
using namespace mapbox::util;

// Forward declaration
struct HPArray;
struct HPTable;
using HPVariant = variant<string,float,recursive_wrapper>;

struct HPArray{
template <typename ...Args>
HPArray(Args ...args){
values.emplace(std::forward(args)...);
}
unordered_map<int,HPVariant> values;
};

struct Visitor{

void operator()(const string &str){
    cout << str <<endl;;
}

void operator()(const float &value){
    cout << value <<endl;
}

void operator()(HPArray array){
    for (size_t i = 0; i < array.values.size(); i++)
    {
        apply_visitor(*this,array.values[i]);
    }
}

};

int main()
{
HPArray ar;
ar.values[0] = HPVariant("String");
ar.values[1] = 2.0f;

HPVariant var;
var.set<HPArray>(ar);
Visitor visitor;
apply_visitor(visitor,var);
return 0;

}

As far as I see, it seems to me that there is a precondition to variant::set<T>(). T shall be in variant::Types.... Take a look at mapbox/variant.hpp:{704, 705}.

You should use T equals mapbox::util::recursive_wrapper<HPArray> instead of HPArray.

Demo:

struct HPArray;
using HPVariant = mapbox::util::variant<
    std::string,
    float,
    mapbox::util::recursive_wrapper<HPArray>
>;
struct HPArray { /*...*/ };

int main()
{
    HPVariant var;
    //It should be: var.set<mapbox::util::recursive_wrapper<HPArray>>(...)
    var.set<HPArray>(HPArray{}); 
    mapbox::util::apply_visitor([](auto&& o){ /*...*/ }, var);
}

BTW, is there a reason to maintain variant::set<T>() to 2.0.0?