mercredi 7 juin 2017

How can I use SFINAE to prevent narrowing in a template function?

I am trying to implement basic arithmetic operations for a Vector class and would like to support mixing underlying types while preventing narrowing from occurring.

template <typename T1,typename T2>
Vector<T1> operator+( Vector<T1> lhs, const Vector<T2>& rhs, std::enable_if< ! is_narrowing_conversion<T2,T1>::value >::type* = nullptr )
{ return lhs += rhs; }

I would like to implement is_narrowing_conversion so that it will only allow the conversion if the types do not narrow. Here are some examples:

Vector<double> a = Vector<double>() + Vector<float>(); //OK
Vector<float> a = Vector<float> + Vector<double>; //Fails to find the operator+ function

In the end I would like to write a second template operator+ function that will handle the inverse case by returning a Vector.

I found this post with an incomplete example. But it is insufficient as he notes that it disallows uint8_t to uint64_t conversions.

I also discovered Daniel Krügler's paper on fixing is_constructible. Specifically in this paper he mentions using list-initialization which already has the narrowing semantics working but I'm not sure how to convert what he mentions into a proper trait that I can use for SFINAE template deduction.

Aucun commentaire:

Enregistrer un commentaire