chriskohlhoff / asio

Asio C++ Library
http://think-async.com/Asio
4.86k stars 1.21k forks source link

error: ‘error’ is not a member of ‘asio::placeholders’ + error: ‘bytes_transferred’ is not a member of ‘asio::placeholders’ #316

Open marcoippolito opened 6 years ago

marcoippolito commented 6 years ago

Hi, in compiling the tutorial example: http://think-async.com/Asio/asio-1.10.6/doc/asio/tutorial/tutdaytime6/src.html

`
#include <ctime>
#include <iostream>
#include <string>
//#include <boost/array.hpp>
#include <array>
//#include <boost/bind.hpp>
#include <functional> //std::bind
//#include <boost/shared_ptr.hpp>
#include <memory> // shared_ptr
#include <asio.hpp>

using asio::ip::udp;

std::string make_daytime_string()
{
  using namespace std; // For time_t, time and ctime;
  time_t now = time(0);
  return ctime(&now);
}

class udp_server
{
public:
  udp_server(asio::io_service& io_service)
    : socket_(io_service, udp::endpoint(udp::v4(), 13))
  {
    start_receive();
  }

private:
  void start_receive()
  {
    socket_.async_receive_from(
        asio::buffer(recv_buffer_), remote_endpoint_,
        std::bind(&udp_server::handle_receive, this,
          asio::placeholders::error,
          asio::placeholders::bytes_transferred));
  }

  void handle_receive(const asio::error_code& error,
      std::size_t /*bytes_transferred*/)
  {
    if (!error || error == asio::error::message_size)
    {
      std::shared_ptr<std::string> message(
           new std::string(make_daytime_string()));

      socket_.async_send_to(asio::buffer(*message), remote_endpoint_,
          std::bind(&udp_server::handle_send, this, message,
            asio::placeholders::error,
            asio::placeholders::bytes_transferred));

      start_receive();
    }
  }

  void handle_send(std::shared_ptr<std::string> /*message*/,
      const asio::error_code& /*error*/,
      std::size_t /*bytes_transferred*/)
  {
  }

  udp::socket socket_;
  udp::endpoint remote_endpoint_;
  std::array<char, 1> recv_buffer_;
};

int main()
{
  try
   {
    asio::io_service io_service;
    udp_server server(io_service);
    io_service.run();
  }
  catch (std::exception& e)
   {
    std::cerr << e.what() << std::endl;
  }

  return 0;
}
`

`g++ -std=c++17 -DASIO_STANDALONE asynchronousUDPdaytimeServer.cpp -pthread  
-oasynchronousUDPdaytimeServer
asynchronousUDPdaytimeServer.cpp: In member function ‘void udp_server::start_receive()’:
asynchronousUDPdaytimeServer.cpp:48:31: error: ‘error’ is not a member of ‘asio::placeholders’
           asio::placeholders::error,
                               ^~~~~
asynchronousUDPdaytimeServer.cpp:48:31: note: suggested alternative:
In file included from /usr/include/asio/detail/impl/posix_mutex.ipp:24,
                 from /usr/include/asio/detail/posix_mutex.hpp:71,
                 from /usr/include/asio/detail/mutex.hpp:25,
                 from /usr/include/asio/detail/service_registry.hpp:20,
                 from /usr/include/asio/impl/execution_context.hpp:20,
                 from /usr/include/asio/execution_context.hpp:406,
                 from /usr/include/asio/detail/scheduler.hpp:21,
                 from /usr/include/asio/system_context.hpp:19,
                 from /usr/include/asio/impl/system_executor.hpp:22,
                 from /usr/include/asio/system_executor.hpp:127,
                 from /usr/include/asio/associated_executor.hpp:21,
                 from /usr/include/asio.hpp:19,
                 from asynchronousUDPdaytimeServer.cpp:22:
/usr/include/asio/error.hpp:64:11: note:   ‘asio::error’
 namespace error {
           ^~~~~
asynchronousUDPdaytimeServer.cpp:49:31: error: ‘bytes_transferred’ is not a member of   
‘asio::placeholders’
           asio::placeholders::bytes_transferred));
                               ^~~~~~~~~~~~~~~~~
asynchronousUDPdaytimeServer.cpp: In member function ‘void udp_server::handle_receive(const 
error_code&, std::size_t)’:
asynchronousUDPdaytimeServer.cpp:62:33: error: ‘error’ is not a member of ‘asio::placeholders’
             asio::placeholders::error,
                                 ^~~~~
asynchronousUDPdaytimeServer.cpp:62:33: note: suggested alternative:
In file included from /usr/include/asio/detail/impl/posix_mutex.ipp:24,
                 from /usr/include/asio/detail/posix_mutex.hpp:71,
                 from /usr/include/asio/detail/mutex.hpp:25,
                 from /usr/include/asio/detail/service_registry.hpp:20,
                 from /usr/include/asio/impl/execution_context.hpp:20,
                 from /usr/include/asio/execution_context.hpp:406,
                 from /usr/include/asio/detail/scheduler.hpp:21,
                 from /usr/include/asio/system_context.hpp:19,
                 from /usr/include/asio/impl/system_executor.hpp:22,
                 from /usr/include/asio/system_executor.hpp:127,
                 from /usr/include/asio/associated_executor.hpp:21,
                 from /usr/include/asio.hpp:19,
                 from asynchronousUDPdaytimeServer.cpp:22:
/usr/include/asio/error.hpp:64:11: note:   ‘asio::error’
 namespace error {
           ^~~~~
asynchronousUDPdaytimeServer.cpp:63:33: error: ‘bytes_transferred’ is not a member of   
‘asio::placeholders’
             asio::placeholders::bytes_transferred));
                                 ^~~~~~~~~~~~~~~~~
`   

What do I have to do to solve the problem? Marco

dmxvlx commented 6 years ago

You can fix it by:

#define ASIO_STANDALONE 1

void start_receive()
  {
    socket_.async_receive_from(
        asio::buffer(recv_buffer_), remote_endpoint_,
        std::bind(&udp_server::handle_receive, this,
          std::placeholders::_1,
          std::placeholders::_2));
  }

But you will get error in ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT macros. There are no support for std::bind.

I have same problem (

amir110 commented 5 years ago

Same error here? How to fix it?

raJeev-M commented 5 years ago

You can fix it by:

#define ASIO_STANDALONE 1

void start_receive()
  {
    socket_.async_receive_from(
        asio::buffer(recv_buffer_), remote_endpoint_,
        std::bind(&udp_server::handle_receive, this,
          std::placeholders::_1,
          std::placeholders::_2));
  }

But you will get error in ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT macros. There are no support for std::bind.

I have same problem (

looks like, asio::placeholders will be enabled for boost.bind. and the compiler flag -DASIO_STANDALONE indicates, non-boost, standalone version of asio..I suppose.

But you will get error in ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT macros.

The completion-token signature for async_send_to should look something like void(std::error_code, std::size_t)

handle_send(error_code,size_t) can you refer to asio document and confirm whether your handlers comply with asio handler's signature requirement?

raJeev-M commented 5 years ago

Same error here? How to fix it?

use std::bind; Refer to asio's document and confirm whether your handlers comply with asio handler's signature requirement?

amir110 commented 5 years ago

yes, using std::bind solves the problem