I have been trying to write a very simple piece of code but it doesn't seems to work and I am unable to make any sense out of the compiler error.
code:
#include <iostream>
#include <sstream>
#include <functional>
class c
{
public:
void test(std::stringstream ss){
std::cout<<ss.str()<<std::endl;
}
void test2(std::stringstream ss){
const auto bound=std::bind(&c::test,this, ss);
std::function<void()> f(bound);
f();
}
};
void test1(const std::stringstream ss){
std::cout<<ss.str()<<std::endl;
}
int main(){
std::stringstream ss;
ss<<"hello world";
//first
const auto bound=std::bind(&test1,ss);
std::function<void()> f(bound);
f();
//second
C obj;
obj.test2(ss);
return 0;
}
error:
bind.cpp:14:32: error: no matching function for call to ‘std::function<void()>::function(const std::_Bind<std::_Mem_fn<void (c::*)(std::__cxx11::basic_stringstream<char>)>(c*, std::__cxx11::basic_stringstream<char>)>&)’
std::function<void()> f(bound);
^
bind.cpp:30:31: error: no matching function for call to ‘std::function<void()>::function(const std::_Bind<void (*(std::__cxx11::basic_stringstream<char>))(std::__cxx11::basic_stringstream<char>)>&)’
std::function<void()> f(bound);
^
I am compiling with: g++ -std=c++14 bind.cpp
.
I see here where the accepted answer suggested to use lambdas instead of std::bind but, can anybody tell why both first and second usage in the above code does not work?
The problems you are facing have to do with the fact that std::stringstream
does not have a copy constructor.
The problems can be resolved by using const std::stringstream&
as argument types instead of std::stringstream
in couple of functions.
#include <iostream>
#include <sstream>
#include <functional>
class c
{
public:
// Change the argument to a const&
void test(std::stringstream const& ss){
std::cout<<ss.str()<<std::endl;
}
// Use std::cref to use a const& in the call to std::bind
void test2(std::stringstream ss){
const auto bound=std::bind(&c::test,this, std::cref(ss));
std::function<void()> f(bound);
f();
}
};
// Change the argument to a const&
void test1(const std::stringstream & ss){
std::cout<<ss.str()<<std::endl;
}
int main(){
std::stringstream ss;
ss<<"hello world";
//first
// Use std::cref to use a const& in the call to std::bind
const auto bound = std::bind(&test1, std::cref(ss));
std::function<void()> f = bound;
f();
return 0;
}