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?
source to share
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).
source to share