I believe my understanding of boost::mpl::set must be fundamentally flawed. I thought it only allowed unique types.
But the following code compiles:
#include <boost/mpl/set.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/accumulate.hpp>
#include <boost/mpl/plus.hpp>
#include <boost/mpl/int.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/mpl/sizeof.hpp>
#include <boost/mpl/assert.hpp>
using namespace boost::mpl;
typedef set<long,float,long> my_set; //long repeated in set?
typedef vector<long,float,long> my_vec; //seems reasonable
typedef accumulate<
my_set
, int_<0>
, plus<_1, sizeof_<_2>>
>::type set_size;
typedef accumulate<
my_vec
, int_<0>
, plus<_1, sizeof_<_2>>
>::type vec_size;
BOOST_MPL_ASSERT_RELATION( vec_size::value, ==, sizeof(long)+sizeof(float)+sizeof(long) );
//why does the following line compile?
//shouldn't the size be sizeof(long)+sizeof(float) instead?
BOOST_MPL_ASSERT_RELATION( set_size::value, ==, sizeof(long)+sizeof(float)+sizeof(long) );
Look again at the documentation.
The list of types T1, T2, T3, ..., TN
used to construct a set must not contain any duplicates. (Or put differently - the set<T1, T2, ..., TN>
construct only has a well defined meaning if T1, T2, T3, ..., TN
does not contain any duplicates).
Later on in the documentation there is an example of how to construct a set from a list of elements which may contain duplicates:
typedef fold<
vector<long,float,long>
, set0<>
, insert<_1,_2>
>::type s;
BOOST_MPL_ASSERT_RELATION( size<s>::value, ==, 2 );
The set invariants are only enforced if you use the set interface to create the set.