Aly
Aly

Reputation: 16255

C++: tusing boost unordered_map error:no matching function call

I have the following code:

struct STFRandomTreeFunction { typedef double (*function_ptr)(const STFDataPoint& data, boost::unordered_map& preloaded_images); };

struct STFRandomTreeFunctor
{
private:
    boost::unordered_map<std::string, cv::Mat> *image_cache;
    STFRandomTreeFunction::function_ptr function;
    std::string function_id;

public:
    STFRandomTreeFunctor(boost::unordered_map<std::string, cv::Mat>& cache, STFRandomTreeFunction::function_ptr function, std::string function_id)
    :image_cache(&cache), function(function), function_id(function_id){}

    std::string get_function_id(){
        return function_id;
    }

    double operator()(const TrainingDataPoint& data_point){
        return function(data_point, *image_cache);
    }
};

unordered_map<string, STFRandomTreeFunctor> lut;

double a(const STFDataPoint& b, unordered_map<string, Mat>& c){
    return 5;
}

int main(int argc, char* argv[]) {

    unordered_map<string, Mat> cache;
    lut["a"] = STFRandomTreeFunctor(cache, a, "a");
}

when I try to build I get the following error: boost/unordered/detail/allocate.hpp:262:1: error: no matching function for call to ‘STFRandomTreeFunctor::STFRandomTreeFunctor()’

But I have no idea why boost is trying to call STFRandomTreeFunctor(), is this because when we create the empty map, it tries to create a STFRandomTreeFunctor? If so, how can I work around this?

Thanks

Upvotes: 0

Views: 651

Answers (3)

BigBoss
BigBoss

Reputation: 6914

When you use lut["a"] in your main function, map should return a reference to an initialized value of type STFRandomTreeFunctor and as you see, it have no parameter to create and initialize that instance, so it use default constructor of your class and your class have no default constructor. so you should either, write a default constructor for your class or use:

lut.insert( std::make_pair("a", STFRandomTreeFunctor(cache, a, "a")) );

Upvotes: 1

xtofl
xtofl

Reputation: 41509

The call

lut["a"] = x;

will first create an empty entry in themap (cfr. operator[]: "Effects: If the container does not already contain an elements with a key equivalent to k, inserts the value std::pair<key_type const, mapped_type>(k, mapped_type())"). To construct mapped_type() it needs a default constructor.

If you want to avoid that, use the insert function:

bool inserted=lut.insert( std::make_pair("a",x) ).second;
assert(inserted); // unless it's ok to not overwrite already inserted keys

But this way, you'll need a copy constructor (or a move-constructor), since the newly created pair will be copied into the map.

Upvotes: 1

Victor Parmar
Victor Parmar

Reputation: 5789

Put your struct definitions on top, basically it's trying to construct the unordered_map<string, STFRandomTreeFunctor> lut; but can't find the definition for your struct :)

struct STFRandomTreeFunction
{
    typedef double (*function_ptr)(const STFDataPoint& data, boost::unordered_map<std::string, cv::Mat>& preloaded_images);
};

struct STFRandomTreeFunctor
{
private:
    boost::unordered_map<std::string, cv::Mat> *image_cache;
    STFRandomTreeFunction::function_ptr function;
    std::string function_id;

public:
    STFRandomTreeFunctor(boost::unordered_map<std::string, cv::Mat>& cache, STFRandomTreeFunction::function_ptr function, std::string function_id)
    :image_cache(&cache), function(function), function_id(function_id){}

    std::string get_function_id(){
        return function_id;
    }

    double operator()(const TrainingDataPoint& data_point){
        return function(data_point, *image_cache);
    }
};

unordered_map<string, STFRandomTreeFunctor> lut;

double a(const STFDataPoint& b, unordered_map<string, Mat>& c){
    return 5;
}

int main(int argc, char* argv[]) {

    unordered_map<string, Mat> cache;
    lut["a"] = STFRandomTreeFunctor(cache, a, "a");
}

Upvotes: 0

Related Questions