I have used BOOST_STRONG_TYPEDEF
before, mainly with std::string
and I got satisfactory results:
#include <boost/serialization/strong_typedef.hpp>
#include <iostream>
BOOST_STRONG_TYPEDEF(std::string, TIMER_ID)
BOOST_STRONG_TYPEDEF(std::string, PROCESS_ID)
int main()
{
TIMER_ID t_id("Timer");
PROCESS_ID p_id("Process");
if (t_id == p_id)
std::cout << "They are equal!" << std::endl;
}
The previous code fails to compile as expected:
In file included from /usr/include/boost/serialization/strong_typedef.hpp:26:0,
from types.cpp:1:
/usr/include/boost/operators.hpp: In instantiation of ‘bool boost::operator==(const std::__cxx11::basic_string<char>&, const PROCESS_ID&)’:
types.cpp:12:14: required from here
/usr/include/boost/operators.hpp:144:64: error: no match for ‘operator==’ (operand types are ‘const PROCESS_ID’ and ‘const std::__cxx11::basic_string<char>’)
friend bool operator==(const U& y, const T& x) { return x == y; }
However, this code compiles just fine:
#include <boost/serialization/strong_typedef.hpp>
#include <iostream>
BOOST_STRONG_TYPEDEF(unsigned int, TIMER_ID)
BOOST_STRONG_TYPEDEF(unsigned int, PROCESS_ID)
int main()
{
TIMER_ID t_id(12);
PROCESS_ID p_id(12);
if (t_id == p_id)
{
std::cout << "They are equal!" << std::endl;
std::cout << "Their sum is " << t_id + p_id << std::endl;
}
}
This doesn't seem strong at all! I would expect to not be able to compare or add objects of two different types without a static_cast
.
Reading http://www.boost.org/doc/libs/1_63_0/libs/serialization/doc/strong_typedef.html , it seems that your example using boost compiles because the types created by boost are substitutable to the original type which are comparable.
Johnathan Boccara from fluentcpp provides an implementation of strong types on its github that should be what you want:
#include <cassert>
#include "NamedType/named_type.hpp"
int main() {
using TIMER_ID =
fluent::NamedType<unsigned int, struct TimerIdTag, fluent::Comparable>;
using PROCESS_ID =
fluent::NamedType<unsigned int, struct ProcessIdTag, fluent::Comparable>;
TIMER_ID a(123);
PROCESS_ID b(456);
assert(a == a);
// assert(a == b); doesn't compile
return 0;
}