pandoragami
pandoragami

Reputation: 5575

boost-asio compilation failure (initialization list in a C++ class)?

I'm trying to compile this code

#ifndef TCPIP_H
#define TCPIP_H

#include <cstdlib>
#include <cstring>
#include <iostream>
#include <boost/asio.hpp>

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

enum { max_length = 1024 };

class TCPIP
{
        private:

            boost::asio::io_service io_service;
            tcp::resolver resolver;
            tcp::resolver::query query;
            tcp::resolver::iterator iterator;
            tcp::socket s;

        public:

        TCPIP():resolver(io_service),
        query("127.0.0.1", "2345"),
        iterator(resolver.resolve(query)),
        s(io_service),
        boost::asio::connect(s, iterator)
        {}
        ~TCPIP(){}
        void IO()
        {
            std::cout << "Enter message: ";
            char request[max_length];
            std::cin.getline(request, max_length);
            size_t request_length = std::strlen(request);
            boost::asio::write(s, boost::asio::buffer(request, request_length));

            char reply[max_length];
            size_t reply_length = boost::asio::read(s,
            boost::asio::buffer(reply, request_length));
            std::cout << "Reply is: ";
            std::cout.write(reply, reply_length);
            std::cout << "\n";
        }
};
#endif

and I get these errors

c:\program files\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.4.1\..\..\..\..\include\boost\asio\detail\config.hpp|205|warning: #warning Please define _WIN32_WINNT or _WIN32_WINDOWS appropriately.|
c:\program files\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.4.1\..\..\..\..\include\boost\asio\detail\config.hpp|206|warning: #warning For example, add -D_WIN32_WINNT=0x0501 to the compiler command line.|
c:\program files\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.4.1\..\..\..\..\include\boost\asio\detail\config.hpp|207|warning: #warning Assuming _WIN32_WINNT=0x0501 (i.e. Windows XP target).|
C:\Documents and Settings\My Documents\project5\erlang_connect\TCPIP.h||In constructor 'TCPIP::TCPIP()':|
C:\Documents and Settings\My Documents\project5\erlang_connect\TCPIP.h|26|error: expected class-name before '(' token|
C:\Documents and Settings\My Documents\project5\erlang_connect\TCPIP.h|26|error: expected '{' before '(' token|
C:\Documents and Settings\My Documents\project5\erlang_connect\erlang_connect.cpp||In function 'int main()':|
C:\Documents and Settings\My Documents\project5\erlang_connect\erlang_connect.cpp|7|error: expected primary-expression before ';' token|
C:\Documents and Settings\My Documents\project5\erlang_connect\erlang_connect.cpp|5|warning: unused variable 'INTERFACE'|
||=== Build finished: 3 errors, 4 warnings ===|

Basically the question relates to the initializer list and the problem with declaring boost::asio::connect(s, iterator). This was the original Boost source code used to make this (the boost blocking tcp-client). I tried using pointers but the boost library doesn't like that idea!

//
// blocking_tcp_echo_client.cpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2012 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 <cstdlib>
#include <cstring>
#include <iostream>
#include <boost/asio.hpp>

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

enum { max_length = 1024 };

int main(int argc, char* argv[])
{
  try
  {
    if (argc != 3)
    {
      std::cerr << "Usage: blocking_tcp_echo_client <host> <port>\n";
      return 1;
    }

    boost::asio::io_service io_service;

    tcp::resolver resolver(io_service);
    tcp::resolver::query query(tcp::v4(), argv[1], argv[2]);
    tcp::resolver::iterator iterator = resolver.resolve(query);

    tcp::socket s(io_service);
    boost::asio::connect(s, iterator);

    using namespace std; // For strlen.
    std::cout << "Enter message: ";
    char request[max_length];
    std::cin.getline(request, max_length);
    size_t request_length = strlen(request);
    boost::asio::write(s, boost::asio::buffer(request, request_length));

    char reply[max_length];
    size_t reply_length = boost::asio::read(s,
        boost::asio::buffer(reply, request_length));
    std::cout << "Reply is: ";
    std::cout.write(reply, reply_length);
    std::cout << "\n";
  }
  catch (std::exception& e)
  {
    std::cerr << "Exception: " << e.what() << "\n";
  }

  return 0;
}

Upvotes: 0

Views: 505

Answers (1)

Tanner Sansbury
Tanner Sansbury

Reputation: 51961

Within an initializer list, the expressions needs to invoke a constructor on either a member of parent class. To resolve this, simply move boost::asio::connect() to the constructor body.

TCPIP()
  : resolver(io_service),              // calls resolver constructor
    query("127.0.0.1", "2345"),        // calls query constructor
    iterator(resolver.resolve(query)), // calls iterator constructor
    s(io_service)                      // calls socket constructor
{
  boost::asio::connect(s, iterator);
}

Also, consider whether or not the resolver, query, and iterator are needed to be accessible throughout the lifespan of the TCPIP object. It may be worth having them be automatic variables within the TCPIP's constructor, resulting in something like:

TCPIP()
  : s(io_service)
{
  tcp::resolver resolver(io_service);
  tcp::resolver::iterator iterator =
    resolver.resolve(tcp::resolver::query(("127.0.0.1", "2345"));
  boost::asio::connect(s, iterator);
}

Upvotes: 2

Related Questions