i'm using boost::asio, i want to know why there is error when i use different overload;
```
#include<boost/asio.hpp>
using namespace boost::asio;
int main(int argc,char* argv[]){
io_service ios;
ip::tcp::acceptor acc(ios);
}
```
it can run when i use the command"g++ -o server server.cpp -lboost_system -lboost_thread -lpthread"
there is another situation:
```
#include<boost/asio.hpp>
using namespace boost::asio;
int main(int argc,char* argv[]){
io_service ios();
ip::tcp::acceptor acc(ios);
}
```
it cant run and there is the errorinfo:
In file included from /usr/include/boost/asio/executor.hpp:338,
from /usr/include/boost/asio/basic_socket.hpp:27,
from /usr/include/boost/asio/basic_datagram_socket.hpp:20,
from /usr/include/boost/asio.hpp:24,
from server.cpp:1:
/usr/include/boost/asio/impl/executor.hpp: In instantiation of ‘boost::asio::execution_context& boost::asio::executor::impl< <template-parameter-1-1>, <template-parameter-1-2> >::context() [with Executor = boost::asio::io_context (*)(); Allocator = std::allocator<void>]’:
/usr/include/boost/asio/impl/executor.hpp:177:22: required from here
/usr/include/boost/asio/impl/executor.hpp:179:22: error: request for member ‘context’ in ‘((boost::asio::executor::impl<boost::asio::io_context (*)(), std::allocator<void> >*)this)->boost::asio::executor::impl<boost::asio::io_context (*)(), std::allocator<void> >::executor_’, which is of non-class type ‘boost::asio::io_context (*)()’
179 | return executor_.context();
| ~~~~~~~~~~^~~~~~~
io_service ios();
This declares a function called ios returning io_service. This is known as the "Most Vexing Parse".
Either use {} instead of () (since C++11) or just leave the parentheses.
Related
Upgrading from boost 1.76 to 1.79 caused a regression in some code I have been working on. This regression comes in the following build error:
In file included from .../boost/json/value.hpp:20,
from <list of includes>
from .../a.cpp
.../boost/json/string.hpp: In member function ‘int boost::json::string::compare(boost::json::string_view) const’:
.../boost/json/string.hpp:1948: error: call of overloaded ‘basic_string_view(const boost::json::string&)’ is ambiguous
return string_view(*this).compare(sv);
In file included from .../boost/json/string_view.hpp:14,
from <lsit of includes>
from .../a.cpp
.../boost/core/detail/string_view.hpp:391: note: candidate: ‘boost::core::basic_string_view<Ch>::basic_string_view(const std::basic_string_view<Ch, std::char_traits<_CharT> >&) [with Ch = char]’
basic_string_view( std::basic_string_view<Ch, std::char_traits<Ch> > const& str ) BOOST_NOEXCEPT: p_( str.data() ), n_( str.size() )
.../boost/core/detail/string_view.hpp:335: note: candidate: ‘constexpr boost::core::basic_string_view<char>::basic_string_view(const boost::core::basic_string_view<char>&)’
template<class Ch> class basic_string_view
.../boost/core/detail/string_view.hpp:335: note: candidate: ‘constexpr boost::core::basic_string_view<char>::basic_string_view(boost::core::basic_string_view<char>&&)’
Here is some example code that I reproduced this with: (GCC 8.2.1, std=c++17)
#include <string>
#include <boost/json.hpp>
#include <boost/json/src.hpp>
int main(int argc, char** argv)
{
return 0;
}
Note it builds with std=c++11 or c++14, however c++17 is a requirment of this project. This error only occurs on linux with GCC. This code builds on Windows with MSVC.
Are there any possible workarounds?
I have tried a couple different tricks using "using" and different namespaces but with the templating it's hard for me to to figure out what is happeneing enough to fix it. I hope I can get this working without changing JSON libraries, or with some other workaround.
Note this build error does not exist with boost 1.76.
In my program I have a Master class (grpc async client) which distributes work to all the Workers (grpc async servers), and it does this via a class called WorkerClient which handles all communication overhead.
My Master class tries to setup a (detached) background thread to wait for the response from the server, and this is where my difficulty arises.
One strategy I've tried was to make my "AsyncComplete" function part of the WorkerClient class (identical to an approach for a recent program involving async client-server grpc based on the Async-Greeter tutorial on grpc.io), the class details for this approach are below.
class WorkerClient {
public:
WorkerClient(std::shared_ptr<grpc::Channel> channel);
void MapReduceWork(masterworker::WorkReq);
void AsyncComplete(void *, void *, int);
struct AsyncClientCall {
masterworker::WorkReply reply;
grpc::ClientContext context;
grpc::Status status;
std::unique_ptr<grpc::ClientAsyncResponseReader<masterworker::WorkReply>> rsp_reader;
};
std::mutex mtx;
std::unique_ptr<masterworker::MasterWorker::Stub> stub;
grpc::CompletionQueue cq;
masterworker::WorkReq work_req;
ClientState state;
};
class Master {
public:
Master(const MapReduceSpec&, const std::vector<FileShard>&);
......
private:
std::mutex mtx;
std::vector<FileShard> map_tasks;
std::vector<ReduceTask *> reduce_tasks;
std::vector<WorkerClient *> clients;
std::vector<std::string> m_interm_files;
std::vector<FileShard> shards;
MapReduceSpec mr_config;
};
Here are the relevant function details
void WorkerClient::AsyncComplete(void *c, void *m, int client_num)
{
void *got_tag = NULL;
bool ok = false;
Master *mast = static_cast<Master*>(m);
WorkerClient *client = static_cast<WorkerClient*>(c);
cq.Next(&got_tag, &ok);
if (ok == false) {
fprintf(stderr, "cq->Next false!\n");
return;
}
......
}
The call to create the thread
void Master::RunMapJob()
{
// clients[] is of type WorkerClient
ptr = new std::thread(&WorkerClient::AsyncComplete,
static_cast<void*>(clients[i]), static_cast<void*>(this), i);
ptr->detach();
......
}
And finally, the problem itself
g++ -c master.cc -I../external/include -std=c++11 -g
In file included from /usr/include/c++/4.8/mutex:42:0,
from master.h:3,
from master.cc:2:
/usr/include/c++/4.8/functional: In instantiation of ‘struct std::_Bind_simple<std::_Mem_fn<void (WorkerClient::*)(void*, void*, int)>(void*, void*, int)>’:
/usr/include/c++/4.8/thread:137:47: required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (WorkerClient::*)(void*, void*, int); _Args = {void*, void*, int&}]’
master.cc:223:65: required from here
/usr/include/c++/4.8/functional:1697:61: error: no type named ‘type’ in ‘class std::result_of<std::_Mem_fn<void (WorkerClient::*)(void*, void*, int)>(void*, void*, int)>’
typedef typename result_of<_Callable(_Args...)>::type result_type;
^
/usr/include/c++/4.8/functional:1727:9: error: no type named ‘type’ in ‘class std::result_of<std::_Mem_fn<void (WorkerClient::*)(void*, void*, int)>(void*, void*, int)>’
_M_invoke(_Index_tuple<_Indices...>)
^
make: *** [master.o] Error 1
So far, I have ruled out the obvious things, like not using std::ref to pass variable references to the thread function, and just in general not passing the correct thread function arguments. I have also tried to make AsyncComplete a static stand-alone function, and that didn't work either because the call to cq.Next (changed to WorkerClient->cq.Next()) was throwing a std::bad_alloc exception (not able to figure that one out either as the CompletionQueue code is behind the scenes).
If it helps, I was able to find the /usr/include/c++/4.8/functional line that seems to be choking during compile (below)
typedef typename result_of<_Callable(_Args...)>::type result_type;
Can anyone help me explain both why this is failing to compile, and what a proper fix might look like? I'm new to posting questions on here so feedback is welcome, and I know this is long, but I wanted to make sure I had all the information.
Thanks in advance.
[System details: ubuntu 14.04, protobufs 3.0, grpc built from source for protobufs 3.0]
This line is the problem:
ptr = new std::thread(&WorkerClient::AsyncComplete,
static_cast<void*>(clients[i]), static_cast<void*>(this), i)
The constructor of std::thread takes a functor and arguments to it. You are supplying &WorkerClient::AsyncComplete without giving an instance of WorkerClient to it. I guess that a client is actually contained in clients[i]. If you try
ptr = new std::thread(std::bind(&WorkerClient::AsyncComplete, clients[i], static_cast<void*>(clients[i]), static_cast<void*>(this), i))
it should compile.
I have a void fun(vector<int> & v) and I want to pass a vector to it when instantiating a thread thread t(fun, v);. In C++14 clang 4 compilation fails, in MSVC it runs passing a copy to function.
#include <thread>
#include <vector>
#include <iostream>
using namespace std;
void fun(vector<int> & v) {
v.push_back(13);
}
int main(){
vector<int> v;
thread t(fun, v);
t.join();
cout << v.size();
}
example of gcc 5.4.0 error:
In file included from /usr/include/c++/5/thread:39:0,
from source_file.cpp:1: /usr/include/c++/5/functional: In instantiation of ‘struct
std::_Bind_simple))(std::vector&)>’:
/usr/include/c++/5/thread:137:59: required from
‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void
(&)(std::vector&); _Args = {std::vector
&}]’ source_file.cpp:12:21: required from here /usr/include/c++/5/functional:1505:61: error: no type named ‘type’ in
‘class std::result_of))(std::vector&)>’
typedef typename result_of<_Callable(_Args...)>::type result_type;
^ /usr/include/c++/5/functional:1526:9: error: no type named ‘type’ in
‘class std::result_of))(std::vector&)>’
_M_invoke(_Index_tuple<_Indices...>)
So 1) what is c++ standard stand on this issue; 2) is there a way around it (not passing a pointer and not +1 extra lambda expression as wrapper)?
As pointed out by Galik in the comment, all you need is std::ref():
thread t(fun, std::ref(v));
Why ?
This is because your function fun() expects a reference to an lvalue. However when you construct your thread(), a copy of your arguments will be passed in the new thread. Unfortunately, the compiler will not be able to instantiate the templates behind the scene with a reference to a temporary copy in this case.
Putting the std::ref(), will cause the reference to the original to be used, and make the whole thing to work as expected.
So I thought I installed GDAL correctly using aptitude, and all my makefile has is
` g++ main.cpp -I/usr/include/mysql -lmysqlclient -I/usr/include/gdal -lgdal1.7.0'
But I am getting this error on my make "ubuntu vm"
`g++ main.cpp -I/usr/include/mysql -lmysqlclient -I/usr/include/gdal -lgdal1.7.0
In file included from /usr/include/c++/4.6/vector:65:0,
from /usr/include/gdal/gdal_priv.h:58,
from main.cpp:5:
/usr/include/c++/4.6/bits/stl_vector.h: In member function ‘std::vector<_Tp, _Alloc>::size_type std::vector<_Tp, _Alloc>::_M_check_len(std::vector<_Tp, _Alloc>::size_type, const char*) const’:
/usr/include/c++/4.6/bits/stl_vector.h:1244:40: error: expected unqualified-id before ‘(’ token
In file included from /usr/include/c++/4.6/vector:66:0,
from /usr/include/gdal/gdal_priv.h:58,
from main.cpp:5:
/usr/include/c++/4.6/bits/stl_bvector.h: In member function ‘std::vector<bool, _Alloc>::size_type std::vector<bool, _Alloc>::_M_check_len(std::vector<bool, _Alloc>::size_type, const char*) const’:
/usr/include/c++/4.6/bits/stl_bvector.h:1026:45: error: expected unqualified-id before ‘(’ token
make: *** [all] Error 1
`
Don't really know how to solve this one
Here is all my code:
#include <iostream>
#include "sql.h"
#include "gdal_priv.h"
#include "cpl_conv.h"
int main(int argc, char ** argv){
GDALDataset *poDataset;
return 0;
}
This looks more like an STL/vector issue than a GDAL specific problem. Something is going wrong when gdal_priv.h does
#include <vector>
I'd first check if you can compile something like this:
#include <vector>
int main(int argc, char ** argv){
std::vector<int> foo;
}
I am trying to experiment the C++11 threads in a way that it accepts a member function of a class as a parameter into the thread constructor as shown in the first code snippet below on line 20 that is marked . The class definition is given in the 2nd code snippet. When this code is compiled, I am getting a bunch of errors shown in the 3rd snippet. Can anyone tell me what I am doing wrong? Thanks.
SNIPPET 1: Thread initialization (main_app.cpp)
#include <thread>
#include "ServiceRegistrar.hpp"
#define SERVER_TYPE 100065
#define SERVER_INST_LOWER 1
#define SERVER_INST_UPPER 2
#define TIMEOUT 500000
int main()
{
ServiceRegistrar sr1(SERVER_TYPE, TIMEOUT, SERVER_INST_LOWER, SERVER_INST_LOWER);
/*LINE 20 is the following*/
std::thread t(&ServiceRegistrar::subscribe2TopologyServer, sr1);
t.join();
sr1.publishForSRs();
}
SNIPPET 2: Class definition
class ServiceRegistrar
{
public:
ServiceRegistrar(int serverType, int serverTimeOut, int serverInstanceLower, int serverInstanceUpper)
: mServerType(serverType),
mServerTimeOut(serverTimeOut),
mServerInstanceLower(serverInstanceLower),
mServerInstanceUpper(serverInstanceUpper)
{ }
void subscribe2TopologyServer();
void publishForSRs();
void publishForServices();
private:
int mServerType;
int mServerTimeOut;
int mServerInstanceLower;
int mServerInstanceUpper;
};
SNIPPET 3: Compilation output
$ g++ -g -c -Wall -std=c++11 main_app.cpp -pthread
In file included from /usr/include/c++/4.7/ratio:38:0,
from /usr/include/c++/4.7/chrono:38,
from /usr/include/c++/4.7/thread:38,
from main_app.cpp:8:
/usr/include/c++/4.7/type_traits: In instantiation of ‘struct std::_Result_of_impl<false, false, std::_Mem_fn<void (ServiceRegistrar::*)()>, ServiceRegistrar>’:
/usr/include/c++/4.7/type_traits:1857:12: required from ‘class std::result_of<std::_Mem_fn<void (ServiceRegistrar::*)()>(ServiceRegistrar)>’
/usr/include/c++/4.7/functional:1563:61: required from ‘struct std::_Bind_simple<std::_Mem_fn<void (ServiceRegistrar::*)()>(ServiceRegistrar)>’
/usr/include/c++/4.7/thread:133:9: required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (ServiceRegistrar::*)(); _Args = {ServiceRegistrar&}]’
main_app.cpp:20:64: required from here
/usr/include/c++/4.7/type_traits:1834:9: error: no match for call to ‘ (std::_Mem_fn<void (ServiceRegistrar::*)()>) (ServiceRegistrar)’
Apparently it's a gcc 4.7 bug...use
std::thread t(&ServiceRegistrar::subscribe2TopologyServer, &sr1);
instead.
EDIT: actually, you probably don't want to be copying sr1 to the thread-local-storage of t, so this is better anyway.
Try:
std::thread t(std::bind(&ServiceRegistrar::subscribe2TopologyServer, sr1));
Hope it helps.