sort() - No matching function for call to 'swap' - c++

Just spent about an hour trying to figure out why I would get 20 error messages of the type "Semantic issue - no matching function for call to 'swap'" when I try to build the following class (in XCode).
test.h
#include <iostream>
#include <string>
#include <vector>
class Test{
std::vector<std::string> list;
void run() const;
static bool algo(const std::string &str1, const std::string &str2);
};
test.cpp
#include "test.h"
void Test::run() const {
std::sort( list.begin(), list.end(), algo );
}
bool Test::algo(const std::string &str1, const std::string &str2){
// Compare and return bool
}
Most of the people with the same problem seem to have made their algorithm a class member instead of a static member, but that is clearly not the problem here.

It turns out it's a very simple problem, but not very obvious to spot (and the error message doesn't do a very good job in helping out either):
Remove the const declaration on run() - voilá.

The compiler refers to swap because std::sort internally uses function swap. However as member function run is declared as constant function
void run() const;
then the object of the class itself is considered as a constant object and hence data member list also is a constant object
std::vector<std::string> list;
So the compiler tries to call swap with parameters that are constant references or even are not references and can not find such a function.

Related

Code not recognizing "#include" statements

I'm writing some header files for a project, but for whatever reason, I'm getting the error "Identifier ' ' is undefined. What am I doing wrong? (It won't recognize string or Boolean as correct)
#include <iomanip>
#include <iostream>
#include <string>
class Camper {
private:
string name;
boolean paid;
public:
void setName(string);
void getName() const;
void setPaid(boolean);
void getPaid() const;
void display() const;
};
Booleans are actually typed as bool in c++.Also the reason it wont recognize string is that string is part of the std namespace.You either need to add using namespace std; under your includes,or else you need to adress string as std::string.Some more elements from the std namespace are Vector,List,etc.You can take a look at those here
EDIT:Also I just noticed your getter/setter methods.A getter method is used so you can access Object attributes without them being public,it returns a type of that attribute.If you want to access name described as an std::string your method should return std::string.Meaning your 2 getters should look like this:
bool getPaid() const;
std::string getName() const;
As L.F. pointed out it is not good practice to use namespaces as it can lead to confusing or even conflicting code.The reference is this

Getting error: expected constructor, destructor, or type conversion before ‘(’ token

I am trying to make functions repository. I have created four files:
Function.hpp, Function.cpp, FunctionsRepository.hpp, FunctionsRepository.cpp
I want to keep pointers to functions in vector of pointers.
//FunctionsRepository.hpp
#ifndef FUNCTIONSREPOSITORY_HPP
#define FUNCTIONSREPOSITORY_HPP
#include <vector>
using namespace std;
class FunctionsRepository {
private:
static vector<double *> pointerToFunctions;
public:
static void addFunction(double * wsk);
};
#endif
//FunctionRepository.cpp
#include "FunctionsRepository.hpp"
void FunctionsRepository::addFunction(double * wsk) {
pointerToFunctions.push_back(wsk);
}
//Functions.hpp
#ifndef FUNCTIONS_HPP
#define FUNCTOINS_HPP
#include "FunctionsRepository.hpp"
int constFunction(int numberOfVehicles);
void linearFunction();
void stepFunction();
#endif
//Funcctions.cpp
#include "Functions.hpp"
double constFunction(double numberOfVehicles){
return numberOfVehicles/2;
}
double (*funcConstant)(double) = constFunction;
//ERROR HERE
FunctionsRepository::addFunction(funcConstant);
I want to add new functions to program as easily as its possible and use it leater in other parts of program.
But I dont get it. Why i am getting this error. The addFunction() method is static, that means I can use it in other classes or parts of program. Vector is static to make sure that is the only one copy for whole program.
Use function wrapper. std::function can stores callable objects. So, your code will contain something like this:
class FunctionsRepository {
private:
// void() - function prototype
static std::vector<std::function<void()>> pointerToFunctions;
public:
static void addFunction(std::function<void()> wsk)
{
pointerToFunctions.push_back(wsk);
}
};
for more information consult official documentation: http://en.cppreference.com/w/cpp/utility/functional/function
I solved It. I received an error because I was calling the FunctionsRepository::addFunction(funcConstant); expression out of any scope. I just created new function to execute this command and thats all.

C++ - Initialiser list for unordered_map of class method function pointers

I'm new to C++11 so I have been experimenting with std::function today and I'm trying to use it to create a hash table for strings to class function pointers for a small assembler I am creating:
assemble.cpp
#include <iostream>
#include <unordered_map>
#include <functional>
#include <vector>
#include <string>
class Assembler {
public:
// Assembles the source file and writes it
bool assemble(std::string output_file);
// Creates the symbol table from a (.s) file
bool create_symbol_table(std::string file_name);
private:
// Hash table for opcode to functions
std::unordered_map<std::string,std::function<bool(std::vector<std::string>)>>
opcode_map =
{
{"add",assemble_data_processing}
};
bool assemble_data_processing(std::vector<std::string> instruction);
};
bool Assembler::assemble_data_processing(std::vector<std::string> instruction) {
std::cout << "Data Processing" << std::endl;
return false;
}
This gives me a compile time error with g++:
g++ -Wall -g -Werror -std=c++11 -o assemble.o assemble.cpp
assemble.cpp:28:5: error: could not convert ‘{{"add", ((Assembler*)this)->Assembler::assemble_data_processing}}’ from ‘<brace-enclosed initializer list>’ to ‘std::unordered_map<std::__cxx11::basic_string<char>, std::function<bool(std::vector<std::__cxx11::basic_string<char> >)> >’
};
^
But if make the function a non-class function then it compiles without problems:
bool assemble_data_processing(std::vector<std::string> instruction) {
std::cout << "Data Processing" << std::endl;
return false;
}
How can I initialise the unordered_map in a brace initialiser list for class methods?
You can use std::bind
std::unordered_map<std::string,std::function<bool(std::vector<std::string>)>>
opcode_map =
{
{"add", std::bind(&Assembler::assemble_data_processing, this, std::placeholders::_1}
};
Or a lambda
std::unordered_map<std::string,std::function<bool(std::vector<std::string>)>>
opcode_map =
{
{"add", [this](std::vector<std::string> instruction){return assemble_data_processing(instruction);}}
};
Or make your function static.
A std::function cannot hold non-bound member functions.
You have three ways to fix this depending on the circumstance.
a) If assemble_data_processing does not use any member data, make it a static member function, and call it a day.
b) If your cache is associated with a single Assembler instance, then bind the function using std::bind, using something similar to:
opcode_map =
{
{"add",std::bind(&Assembler::assemble_data_processing, this, _1)}
};
c) if the Assembler instance is something that gets determined later, then you will have to ditch std::function, and use a good-old function pointer to member function.

Error: no instance of overloaded function, in constructor (C++)

I have a very weird problem... First of all, here are my class's files:
Show.h:
#ifndef SHOW
#define SHOW
#include <iostream>
#include <string>
#include <string.h>
class Show
{
private:
std::string m_time;
int m_serial
public:
Show(const std::string &time, const int &serial);
~Show();
};
#endif
Show.c:
#include "Show.h"
Show::Show(const std::string &time,const int &serial)
{
}
As you can probably see, I only wrote the declaration of the constructor, when the visual studio underlined the second "Show" word in the Show.c file, and told me:
"void Show::Show(const std::string &time,const int &serial)
Show::Show()
Show::Show(const Show &)
Error: no instance of overloaded function "Show::Show" matches the specific type"
And when I stand with the mouse cursor over the constructor function in the Show.h file it looks like that function doesn't exists... I have written some classes in c++ before, and that is the first time anything like that happens to me... help please :(
You forgot to put ; after m_serial field variable. I believe this is the reason of the problem you have. Unfortunately many compilers do not give the exact reason of the problems like this, so you have to be careful with syntax rules.

Calling a member function with member data by using for_each

Dear all, I would like to call a member function (that expects a reference) for each object of (let's say) a vector that is a member of the same class, as the following code shows:
#include <functional>
#include <algorithm>
#include <vector>
#include <iostream>
using namespace std;
struct Stuff {
double x;
};
class Test {
public:
void f1(Stuff & thing);
void f2(void);
vector<Stuff> things;
};
void Test::f1(Stuff & thing) {
; // do nothing
}
void Test::f2(void) {
for_each(things.begin(), things.end(), f1);
}
int main(void)
{
return 0;
}
This codes gives me a compiler error related to unresolved overloaded function type . I have tried also with bind, but it seems that the references requisite in f1 is one problem. I know I am missing something important here, so I take this opportunity to solve my problem and to learn. At the moment, I can't install boost, but I would like to know also if boost is useful to solve this problem. Thanks in advance.
The function you want to call cannot be simply identified by f1 but should be referred to as &Test::f1 (as in : member function f1 of class Test)
Function f1 does not take a single argument : as any non-static member function it has an implicit this parameter of type Test * const
Finally, a standard bind won't be able to do the trick because it doesn't handle parameters passed by reference.
Boost.Bind would indeed be a great option :
std::for_each(things.begin(), things.end(), boost::bind(&Test::f1, this, _1));