Per utilizzare numeric_cast
, la specializzazione numeric_cast_traits
deve essere definita per ogni conversione di tipo. Queste specializzazioni sono già definite con valori predefiniti per i tipi numerici incorporati. È possibile disabilitare la generazione di specializzazioni per i tipi predefiniti definendo BOOST_NUMERIC_CONVERSION_RELAX_BUILT_IN_CAST_TRAITS
(details).
Ecco un piccolo campione in esecuzione.
#include <iostream>
#include <stdexcept>
#define BOOST_NUMERIC_CONVERSION_RELAX_BUILT_IN_CAST_TRAITS
#include <boost/numeric/conversion/cast.hpp>
using namespace std;
struct YourOverflowHandlerPolicy
{
void operator() (boost::numeric::range_check_result r) {
cout << "YourOverflowHandlerPolicy called" << endl;
if (r != boost::numeric::cInRange) {
throw logic_error("Not in range!");
}
};
};
namespace boost { namespace numeric {
template <>
struct numeric_cast_traits<uint32_t, uint64_t>
{
typedef YourOverflowHandlerPolicy overflow_policy;
typedef UseInternalRangeChecker range_checking_policy;
typedef Trunc<uint64_t> rounding_policy;
};
template <>
struct numeric_cast_traits<uint64_t, uint32_t>
{
typedef YourOverflowHandlerPolicy overflow_policy;
typedef UseInternalRangeChecker range_checking_policy;
typedef Trunc<uint32_t> rounding_policy;
};
}} //namespace boost::numeric;
int main()
{
try {
cout << boost::numeric_cast<uint32_t>((uint64_t)1) << endl; // OK
cout << boost::numeric_cast<uint32_t>((uint64_t)1<<31) << endl; // OK
cout << boost::numeric_cast<uint32_t>((uint64_t)1<<32) << endl; // Exception
} catch (...) {
cout << "exception" << endl;
}
return 0;
}
uscita:
YourOverflowHandlerPolicy called
1
YourOverflowHandlerPolicy called
2147483648
YourOverflowHandlerPolicy called
exception
Nota: Ho rilascio spinta 1.55.0, non so il livello minimo rilascio per farlo compilato ma non viene compilato con 1.46.0. Quindi, controlla la tua versione di boost e aggiorna se necessario.