Il codice di seguito viene illustrato il mio problemaproblema C++ Template Metaprogrammazione nella selezione del tipo di
#include <type_traits>
#include <limits>
#include <cstdint>
#include <boost/mpl/if.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/identity.hpp>
/////////////////////////////////////////////////////////////////
// safe_signed_range
template <
std::intmax_t MIN,
std::intmax_t MAX
>
struct safe_signed_range {
};
/////////////////////////////////////////////////////////////////
// safe_unsigned_range
template <
std::uintmax_t MIN,
std::uintmax_t MAX
>
struct safe_unsigned_range {
};
template<class T, class U>
using calculate_max_t = typename boost::mpl::if_c<
std::numeric_limits<T>::is_signed
|| std::numeric_limits<U>::is_signed,
std::intmax_t,
std::uintmax_t
>::type;
template<typename T, typename U>
struct test {
typedef calculate_max_t<T, U> max_t;
static_assert(std::is_same<max_t, std::intmax_t>::value, "unexpected value for max_t");
static_assert(std::is_signed<max_t>::value, "check parameter");
/*
typedef typename boost::mpl::if_c<
std::is_signed<max_t>::value,
safe_signed_range<std::numeric_limits<max_t>::min(), std::numeric_limits<max_t>::max()>,
safe_unsigned_range<std::numeric_limits<max_t>::min(), std::numeric_limits<max_t>::max()>
>::type type;
*/
typedef typename boost::mpl::eval_if_c<
std::is_signed<max_t>::value,
boost::mpl::identity<safe_signed_range<std::numeric_limits<max_t>::min(), std::numeric_limits<max_t>::max()> >,
// error shows up here
boost::mpl::identity<safe_unsigned_range<std::numeric_limits<max_t>::min(), std::numeric_limits<max_t>::max()> >
>::type type;
};
test<int, int> t1;
//test<int, unsigned> t2;
//test<unsigned, int> t3;
//test<unsigned, unsigned> t4;
int main(){
return 0;
}
errore si presenta con Clang compilatore come
/Users/robertramey/WorkingProjects/safe_numerics/test/test_z.cpp:116:50: Non-type template argument evaluates to -9223372036854775808, which cannot be narrowed to type 'std::uintmax_t' (aka 'unsigned long')
Questo sembra gradire Boost Mpl isn selezionando il tipo corretto. Per prima cosa ho sospettato (e in realtà sospetto ancora) che tutti gli argomenti relativi a if venissero espansi, quindi ho deciso di utilizzare eval_if, ma ho comunque riscontrato il problema. Ho incluso static_assert per controllare i parametri e posso farlo fallire con il più semplice dei test, anche se fallisce su tutte le combinazioni. Se qualcuno può spiegare il mio errore a me, sarei grato.
OK - questo ha funzionato - buon lavoro e grazie mille. Naturalmente questa era la mia motivazione per usare la mpl: identità che alla mia mente dovrebbe fare la stessa cosa. Vedrò questo. Grazie ancora. –