Sending and returning STL containers

So far we have passed integers as arguments to the RPC handler and returned integers as well. Note that Thallium is able to understand and serialize all arithmetic types, that is, all integer types (char, long, uint64_t, etc.) and floating point types (float, double, etc.). Provided that the type(s) they contain are serializable, Thallium is also capable of serializing all containers of the C++14 Standard Template Library.

List of containers

Here is a full list of containers that Thallium can serialize.

  • std::array<T>

  • std::complex<T>

  • std::deque<T>

  • std::forward_list<T>

  • std::list<T>

  • std::map<K,V>

  • std::multimap<K,V>

  • std::multiset<T>

  • std::pair<U,V>

  • std::set<T>

  • std::string

  • std::tuple<T...>

  • std::unordered_map<K,V>

  • std::unordered_multimap<K,V>

  • std::unordered_multiset<T>

  • std::unordered_set<T>

  • std::vector<T>

For instance, Thallium will be able to serialize the following type:

std::vector<std:tuple<std::pair<int,double>,std::list<int>>>

Indeed, Thallium knows how to serialize ints and doubles, so it knows how to serialize std::pair<int,double> and std::list<int>, so it knows how to serialize std:tuple<std::pair<int,double>,std::list<int>>, so it knows how to serialize std::vector<std:tuple<std::pair<int,double>,std::list<int>>>.

In order for Thallium to know how to serialize a given type, however, you need to include the proper header in the files containing code requiring serialization. For instance to make Thallium understand how to serialize an std::vector, you need #include <thallium/serialization/stl/vector.hpp>.

The following is a revisited Hello World example in which the client sends its name as an std::string.

Server

#include <string>
#include <iostream>
#include <thallium.hpp>
#include <thallium/serialization/stl/string.hpp>

namespace tl = thallium;

void hello(const tl::request& req, const std::string& name) {
    std::cout << "Hello " << name << std::endl;
}

int main(int argc, char** argv) {

    tl::engine myEngine("tcp://127.0.0.1:1234", THALLIUM_SERVER_MODE);
    myEngine.define("hello", hello).disable_response();

    return 0;
}

Client

#include <string>
#include <thallium.hpp>
#include <thallium/serialization/stl/string.hpp>

namespace tl = thallium;

int main(int argc, char** argv) {

    tl::engine myEngine("tcp", THALLIUM_CLIENT_MODE);
    tl::remote_procedure hello = myEngine.define("hello").disable_response();
    tl::endpoint server = myEngine.lookup("tcp://127.0.0.1:1234");
    std::string name = "Matthieu";
    hello.on(server)(name);

    return 0;
}

Note

We explicitly define std::string name = "Matthieu"; before passing it as an argument. If we were to write hello.on(server)("Matthieu");, the compiler would consider "Matthieu" as a const char* variable, not a std::string, and Thallium is not able to serialize pointers. Alternatively, hello.on(server)(std::string("Matthieu")); is valid.