Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

error C2678: binary '=' : no operator found which takes a left-hand operand of type 'const Recipe' (or there is no acceptable conversion)

I'm trying to sort a vector that contains an int and a string in each element. It is a vector of class type called vector recipes. Getting the above error, here's my code:

In my Recipe.h file

struct Recipe {
public:
    string get_cname() const
    {
        return chef_name;
    }
private:
    int recipe_id;
    string chef_name;

In my Menu.cpp file

void Menu::show() const {
    sort(recipes.begin(), recipes.end(), Sort_by_cname());
}

In my Menu.h file

#include <vector>
#include "Recipe.h"
using namespace std;

struct Sort_by_cname 
{
    bool operator()(const Recipe& a, const Recipe& b)
    {
        return a.get_cname() < b.get_cname();
    }
};

class Menu {
public: 
    void show() const;
private
    vector<Recipe> recipes;
};

What am I doing wrong?

like image 653
Richard Avatar asked Oct 17 '11 23:10

Richard


2 Answers

Menu::show() is declared const, so inside of it Menu::recipes is considered to have been declared as std::vector<Recipe> const.

Obviously, sorting a std::vector<> mutates it, so Menu::show() must not be const (or Menu::recipes must be mutable, but this seems semantically incorrect in this case).

like image 153
ildjarn Avatar answered Oct 07 '22 23:10

ildjarn


You have marked your show method as const which isn't true because it is changing the recipes vector. When I compile the code you have outlined with gnu gcc 4.2.1 the error is specific to disqualifying the const qualifier, not the error you've posted.

You could mark your vector with the keyword mutable but I suspect that isn't what you really want? By marking the vector mutable it ignores the constness the compiler would normally enforce within Menu::show() const of the vector and it gets changed everytime Menu::show() is called. If you really want to use the vector, and not an ordered set like others have suggested, you could add a dirty state flag to let your program know when it should resort, or not.

The following code I have compiles by changing the vector to mutable to show you the difference, but I still recommend that you don't use sort from with a const show method.

#include <vector>
#include <string>

using namespace std;
struct Recipe {
public:
  string get_cname() const
  {
    return chef_name;
  }
private:
  int recipe_id;
  string chef_name;
};

class Menu {
public:
  void show() const;
private:
  mutable vector<Recipe> recipes;
};

struct Sort_by_cname
{
  bool operator()(const Recipe& a, const Recipe& b)
  {
    return a.get_cname() < b.get_cname();
  }
};

void Menu::show() const {
  sort(recipes.begin(), recipes.end(), Sort_by_cname());
}
like image 33
James Avatar answered Oct 07 '22 22:10

James