Exact source listing in Visual Studio 2015


//
// server.cpp
// ~~~~~~~~~~
//
// Copyright (c) 2003-2013 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

#include <ctime>
#include <iostream>
#include <string>
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/asio.hpp>

#include <functional>

using boost::asio::ip::tcp;

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

class tcp_connection
    : public boost::enable_shared_from_this<tcp_connection>
{
public:
    typedef boost::shared_ptr<tcp_connection> pointer;

    static pointer create(boost::asio::io_service& io_service)
    {
        return pointer(new tcp_connection(io_service));
    }

    tcp::socket& socket()
    {
        return socket_;
    }

    void start()
    {
        message_ = make_daytime_string();

        boost::asio::async_write(socket_, boost::asio::buffer(message_),
            boost::bind(&tcp_connection::handle_write, shared_from_this(),
                boost::asio::placeholders::error,
                boost::asio::placeholders::bytes_transferred));
    }

private:
    tcp_connection(boost::asio::io_service& io_service)
        : socket_(io_service)
    {
    }

    void handle_write(const boost::system::error_code& /*error*/,
        size_t /*bytes_transferred*/)
    {
    }

    tcp::socket socket_;
    std::string message_;
};

class tcp_server
{
public:
    tcp_server(boost::asio::io_service& io_service)
        : acceptor_(io_service, tcp::endpoint(tcp::v4(), 13))
    {
        start_accept();
    }

private:
    void start_accept()
    {
        tcp_connection::pointer new_connection =
            tcp_connection::create(acceptor_.get_io_service());

        std::function<void(tcp_connection::pointer new_connection, const
            boost::system::error_code &error)> callback =
            std::bind(&tcp_server::handle_accept, this, new_connection,
                std::placeholders::_1);

        acceptor_.async_accept(new_connection->socket(), callback);
    }

    void handle_accept(tcp_connection::pointer new_connection,
        const boost::system::error_code& error)
    {
        if( !error )
        {
            new_connection->start();
        }

        start_accept();
    }

    tcp::acceptor acceptor_;
};

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

    return 0;
}



Exact output spew from compilation:
This is against boost 1.55, because that's what I have at home. I use 1.62.0 at work and get the exact same errors.


1>  Please define _WIN32_WINNT or _WIN32_WINDOWS appropriately. For example:
1>  - add -D_WIN32_WINNT=0x0501 to the compiler command line; or
1>  - add _WIN32_WINNT=0x0501 to your project's Preprocessor Definitions.
1>  Assuming _WIN32_WINNT=0x0501 (i.e. Windows XP target).
1>d:\programing projects\cplusplus\boost_1_55_0\boost\asio\detail\impl\socket_ops.ipp(1953): warning C4996: 'WSAAddressToStringA': Use WSAAddressToStringW() instead or define _WINSOCK_DEPRECATED_NO_WARNINGS to disable deprecated API warnings
1>  c:\program files (x86)\windows kits\8.1\include\um\winsock2.h(3556): note: see declaration of 'WSAAddressToStringA'
1>d:\programing projects\cplusplus\boost_1_55_0\boost\asio\detail\impl\socket_ops.ipp(2159): warning C4996: 'WSAStringToAddressA': Use WSAStringToAddressW() instead or define _WINSOCK_DEPRECATED_NO_WARNINGS to disable deprecated API warnings
1>  c:\program files (x86)\windows kits\8.1\include\um\winsock2.h(3623): note: see declaration of 'WSAStringToAddressA'
1>d:\programing projects\cplusplus\boost_1_55_0\boost\asio\detail\impl\socket_ops.ipp(2295): warning C4996: 'gethostbyaddr': Use getnameinfo() or GetNameInfoW() instead or define _WINSOCK_DEPRECATED_NO_WARNINGS to disable deprecated API warnings
1>  c:\program files (x86)\windows kits\8.1\include\um\winsock2.h(2216): note: see declaration of 'gethostbyaddr'
1>d:\programing projects\cplusplus\boost_1_55_0\boost\asio\detail\impl\socket_ops.ipp(2344): warning C4996: 'gethostbyname': Use getaddrinfo() or GetAddrInfoW() instead or define _WINSOCK_DEPRECATED_NO_WARNINGS to disable deprecated API warnings
1>  c:\program files (x86)\windows kits\8.1\include\um\winsock2.h(2238): note: see declaration of 'gethostbyname'
1>d:\programing projects\cplusplus\boost_1_55_0\boost\asio\detail\impl\socket_select_interrupter.ipp(62): warning C4996: 'inet_addr': Use inet_pton() or InetPton() instead or define _WINSOCK_DEPRECATED_NO_WARNINGS to disable deprecated API warnings
1>  c:\program files (x86)\windows kits\8.1\include\um\winsock2.h(1850): note: see declaration of 'inet_addr'
1>d:\programing projects\cplusplus\boost_1_55_0\boost\asio\detail\impl\socket_select_interrupter.ipp(75): warning C4996: 'inet_addr': Use inet_pton() or InetPton() instead or define _WINSOCK_DEPRECATED_NO_WARNINGS to disable deprecated API warnings
1>  c:\program files (x86)\windows kits\8.1\include\um\winsock2.h(1850): note: see declaration of 'inet_addr'
1>d:\users\cpisz.christopherpisz\documents\visual studio 2015\projects\consoleapplication1\consoleapplication1\source2.cpp(27): warning C4996: 'ctime': This function or variable may be unsafe. Consider using ctime_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
1>  c:\program files (x86)\windows kits\10\include\10.0.10240.0\ucrt\time.h(475): note: see declaration of 'ctime'
1>d:\programing projects\cplusplus\boost_1_55_0\boost\asio\basic_socket_acceptor.hpp(1015): error C2338: AcceptHandler type requirements not met
1>  d:\users\cpisz.christopherpisz\documents\visual studio 2015\projects\consoleapplication1\consoleapplication1\source2.cpp(91): note: see reference to function template instantiation 'boost::asio::async_result<Handler>::type boost::asio::basic_socket_acceptor<boost::asio::ip::tcp,boost::asio::socket_acceptor_service<Protocol>>::async_accept<Protocol,StreamSocketService,std::function<void (tcp_connection::pointer,const boost::system::error_code &)>&>(boost::asio::basic_socket<Protocol,StreamSocketService> &,AcceptHandler,void *)' being compiled
1>          with
1>          [
1>              Handler=std::function<void (tcp_connection::pointer,const boost::system::error_code &)>,
1>              Protocol=boost::asio::ip::tcp,
1>              StreamSocketService=boost::asio::stream_socket_service<boost::asio::ip::tcp>,
1>              AcceptHandler=std::function<void (tcp_connection::pointer,const boost::system::error_code &)> &
1>          ]
1>  d:\users\cpisz.christopherpisz\documents\visual studio 2015\projects\consoleapplication1\consoleapplication1\source2.cpp(91): note: see reference to function template instantiation 'boost::asio::async_result<Handler>::type boost::asio::basic_socket_acceptor<boost::asio::ip::tcp,boost::asio::socket_acceptor_service<Protocol>>::async_accept<Protocol,StreamSocketService,std::function<void (tcp_connection::pointer,const boost::system::error_code &)>&>(boost::asio::basic_socket<Protocol,StreamSocketService> &,AcceptHandler,void *)' being compiled
1>          with
1>          [
1>              Handler=std::function<void (tcp_connection::pointer,const boost::system::error_code &)>,
1>              Protocol=boost::asio::ip::tcp,
1>              StreamSocketService=boost::asio::stream_socket_service<boost::asio::ip::tcp>,
1>              AcceptHandler=std::function<void (tcp_connection::pointer,const boost::system::error_code &)> &
1>          ]
1>d:\programing projects\cplusplus\boost_1_55_0\boost\asio\basic_socket_acceptor.hpp(1015): error C2064: term does not evaluate to a function taking 1 arguments
1>  d:\programing projects\cplusplus\boost_1_55_0\boost\asio\basic_socket_acceptor.hpp(1015): note: class does not define an 'operator()' or a user defined conversion operator to a pointer-to-function or reference-to-function that takes appropriate number of arguments
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========


&amp somehow got put there from copy pasting? It is an actual amperstand in code.
I am posting via Gmail now. I am not sure if they did it. At work I have to post through nabble, because they have just about everything blocked.

On Tue, Mar 28, 2017 at 9:23 PM, Gavin Lambert via Boost-users <boost-users@lists.boost.org> wrote:
On 29/03/2017 12:02, Christopher Pisz via Boost-users wrote:
Sigh. I know that code wouldn't work. That is my interpretation of what you
gave me. Now you are talking about two arguments and placeholders, but why
would I give it a place holder, when I am giving it the argument directly?
the tcp_connection::pointer argument is new_connection. The placeholder is
for the error code which I am not supplying directly. Either way, it still
fails to compile if you add a std::placeholders::_2 on the end.

You need _1 (and only that) in the functor that is passed to async_accept, since that expects a callback that takes exactly one error_code argument.

You might need other placeholders if elsewhere you're using functors that take more than one argument, as in one previous instance where you were using multiple binds or getting a callback passed in externally to then rebind locally.

Can we just get a compilable working example of the following method while
maintaining the use of the std::function variable? I don't want to bind
directly, I don't want to use  lambda, I want to have an std::function
variable that I can pass to others. It's really a simple 6 line problem....

Just be careful with passing functions outside of the class, as they can have hidden dependencies (eg. the below will UB or crash if something tries to call the callback after tcp_server has been destroyed).

The following code still fails to compile:

    void start_accept()
    {
        tcp_connection::pointer new_connection =
            tcp_connection::create(acceptor_.get_io_service());

        std::function<void(tcp_connection::pointer new_connection, const
boost::system::error_code &amp; error)> callback =
            std::bind(&tcp_server::handle_accept, this, new_connection,
std::placeholders::_1);

        acceptor_.async_accept(new_connection->socket(), callback);
    }

I still can't see your monitor from where I'm sitting, so I don't know what errors it produces.  If you want anything more helpful than guesswork, then tell people what the errors are; don't just say that it fails.  (http://www.catb.org/esr/faqs/smart-questions.html)

First off, is that &amp; actually in your source code or is it only being added when you email?  You need to fix that if it's actually in your code.

Secondly, you shouldn't specify parameter names in the type signature of std::function; just use types.

Otherwise, that code looks like it should work, assuming handle_accept has a compatible signature.



_______________________________________________
Boost-users mailing list
Boost-users@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/boost-users