Compatibility issues between typedefs

I use BOOST_STRONG_TYPEDEF

various types of string based identifiers to prevent abuse. However, I am running into compatibility issues between the original type and its typedef.

I have std::string

one that contains a comma separated list of IDs. I need to save them to a set. The code will look like this:

#include <boost/algorithm/string/split.hpp>
#include <boost/serialization/strong_typedef.hpp>
#include <boost/algorithm/string/classification.hpp>

#include <set>
#include <vector>

BOOST_STRONG_TYPEDEF(std::string, MY_ID)

int main()
{
    std::string line("ID1,ID2,ID3");

    // Use boost::split to get all the strings into a vector
    std::vector<std::string> id_vec;
    boost::split(id_vec, line, boost::is_any_of(","));

    // Generate a set of MY_ID. Do not use range constructor since the compiler
    // error is clearer this way
    std::set<MY_ID> ids;
    for (auto const & id : id_vec)
    {
        ids.insert(id);
    }
}

      

This will not compile as std::string

it cannot be inserted into std::set<MY_ID>

. However, if I declare the vector to be of type std::vector<MY_ID>

, it won't work with boost::split

.

I found it working by adding a temporary variable on insert:

for (auto const & id : id_vec)
{
    MY_ID tmp(id);
    ids.insert(tmp);
}

      

This works, but seems to be a hack. Is there a more concise way?

+3


source to share


1 answer


The whole point of strong typedefs is to require an explicit conversion when creating a strong typedef from its base type. Therefore, use the explicit conversion syntax:

for (auto const & id : id_vec)
{
    ids.insert(MY_ID{id});
}

      



Alternative ways to do the conversion are: static_cast<MY_ID>(id)

and MY_ID(id)

(note that the latter is equivalent to C-style (MY_ID)id

and therefore best avoided).

+3


source







All Articles