1

I created a ServerService namespace for containing a class name server_datetime. Server_datetime class as tutorial at Boost examples, but I improved server_datetime class by using template parameter for inserting io_service ( boost::asio::io_service ) and endpoint ( tcp::endpoint(tcp::v4(),SIZE_DATA) ) objects to template. I follow as example below :

using boost::asio::ip::tcp;
namespace ServerService{
template<typename Service, typename Endpoint>
class server_datetime {
public:
    server_datetime(){
        acceptor_(service_, endpoint_);
        for(;;)
        {
            tcp::socket socket(Service);
            acceptor_.accept(socket);
            std::string message = make_daytime_string;

            boost::system::error_code ignored_error;
            boost::asio::write(socket, boost::asio::buffer(message),boost::asio::transfer_all(), ignored_error);
        }
    }
    std::string make_daytime_string(){
        std::time_t now = std::time(0);
        return std::ctime(&now);
    }
    virtual ~server_datetime();
private:
    tcp::acceptor acceptor_;
    Service service_;
    Endpoint endpoint_;
};
}

Main function called server_datetime class by follow as:

#include "server_datetime.hpp"
using namespace std;
using boost::asio::ip::tcp;
int main() {
    const boost::asio::io_service io_service_;
    const int SIZE_DATA = 13;
    ServerService::server_datetime<io_service_, tcp::endpoint(tcp::v4(),SIZE_DATA)  >  server;
    cout << "" << endl; // prints 
    return 0;
}

After main function compiled by compiler, Compiler show error as:

..\src\connectk.cpp: In function 'int main()':
..\src\connectk.cpp:10: error: 'io_service_' cannot appear in a constant-expression
..\src\connectk.cpp:10: error: 'boost::asio::ip::tcp::v4()' cannot appear in a constant-expression
..\src\connectk.cpp:10: error: a function call cannot appear in a constant-expression
..\src\connectk.cpp:10: error: template argument 1 is invalid
..\src\connectk.cpp:10: error: template argument 2 is invalid
..\src\connectk.cpp:10: error: invalid type in declaration before ';' token
R.Chatsiri
  • 97
  • 2
  • 11

3 Answers3

4
std::string message = make_daytime_string;

you have forgotten the (), should be :

 std::string message = make_daytime_string();
Guillaume07
  • 9,618
  • 13
  • 57
  • 130
2

The server_datetime template expects type names (it says so right at the top of the first source code), but you supply values instead.

Perhaps you shouldn't create the io_service_ in main, but let the server do that?

Bo Persson
  • 86,087
  • 31
  • 138
  • 198
2

Template parameters are for specifying types and constant values at compile-time, not for injecting objects at run-time; that is what ordinary function/constructor parameters are for. So in this case, if you provide the service and endpoint to the server, pass them as arguments to the constructor.

There are also a few other errors in the code; here are a few corrections (although there may still be problems, and I may have introduced some myself):

namespace ServerService{

// Put 'using' declarations inside the namespace,
// to avoid polluting the global namespace
using boost::asio::ip::tcp;
using boost::asio::io_service;

// Not a template - pass runtime objects as constructor arguments
class server_datetime {
public:
    server_datetime(io_service & service, tcp::endpoint const & endpoint) :
        // Initialise members in an initialiser list
        acceptor_(service, endpoint),
        service_(service)
    {}

    // Put the main loop in a separate function; it's rather odd
    // to have a constructor that doesn't return.
    void run(){
        for(;;)
        {
            // Argument must be the object service_, not the type Service
            tcp::socket socket(service_); 
            acceptor_.accept(socket);
            std::string message = make_daytime_string(); // missing parentheses

            boost::system::error_code ignored_error;
            boost::asio::write(socket, boost::asio::buffer(message),boost::asio::transfer_all(), ignored_error);
        }
    }
    std::string make_daytime_string(){
        std::time_t now = std::time(0);
        return std::ctime(&now);
    }
    // No need for a virtual destructor - this class is not polymorphic
private:
    boost::asio::io_service & service_; // must be a reference - io_service is not copyable
    tcp::acceptor acceptor_;
    // No need to store the endpoint - it's only used to initialise acceptor_.
};
}

int main() {
    using boost::asio::ip::tcp;

    // can't be const if you want to use it
    boost::asio::io_service io_service_;

    // renamed SIZE_DATA and given it the same type as the constructor argument
    const unsigned short port = 13; 

    ServerService::server_datetime server(io_service_, tcp::endpoint(tcp::v4(),port));
    server.run();
    // no need to explicitly return zero, unless you want to.
}
Mike Seymour
  • 235,407
  • 25
  • 414
  • 617
  • Can I use template parameter lists are "class"? such as 'template'If i want to injecting objects. [link](http://stackoverflow.com/questions/213121/c-use-class-or-typename-for-template-parameters) – R.Chatsiri Apr 19 '11 at 09:47
  • 1
    @Chatsiri.rat: no, in a template parameter list `class` means the same as `typename`; both declare a type parameter. Templates are instantiated at compile-time, so the only objects you can inject are compile-time constants. If you want to inject run-time objects, that must be done through function or constructor arguments. – Mike Seymour Apr 19 '11 at 09:57
  • I sparaeted main method to class file and ServerService namespace to the header file. Why compiler show cannot created a server instantiated on class file? – R.Chatsiri Apr 21 '11 at 05:36
  • @Chatsiri.rat: because I made a couple of mistakes in the code. I've just corrected it, although there might still be more mistakes. – Mike Seymour Apr 21 '11 at 05:44
  • I solve my problem on main function at class file by improving server instantiated class is `ServerService::server_datetime server(io_service_, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(),port) ); server.run();` – R.Chatsiri Apr 21 '11 at 07:48