From a3bdf1b7a1ec1417f8a0f125e818f11e499342f4 Mon Sep 17 00:00:00 2001 From: Danny Robson Date: Wed, 25 Nov 2015 13:32:29 +1100 Subject: [PATCH] strongdef: disable mismatched T/Tag assignment --- strongdef.hpp | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/strongdef.hpp b/strongdef.hpp index 75c07d1d..bb6e0e5a 100644 --- a/strongdef.hpp +++ b/strongdef.hpp @@ -27,13 +27,33 @@ namespace util { struct strongdef { public: using value_type = T; + using tag_type = Tag; constexpr strongdef () = default; constexpr explicit strongdef (const T &_data): data (_data) { ; } constexpr strongdef (const strongdef &rhs): data (rhs.data) { ; } - strongdef& operator= (const strongdef &rhs) { data = rhs.data; return *this; } - strongdef& operator= (const T &rhs) { data = rhs; return *this; } + // explicitly disable assignment with unequal types or tags. this + // prevents the converion operator getting invoked and falsely + // allowing assignment with differing types or tags. + template + std::enable_if_t< + !std::is_same::value || !std::is_same::value, + strongdef& + > + operator= (const strongdef &rhs) = delete; + + template + std::enable_if_t< + std::is_same::value && std::is_same::value, + strongdef& + > + operator= (const strongdef &rhs) + { data = rhs.data; return *this; } + + // simple value_type assignment. + strongdef& operator= (const T &rhs) + { data = rhs; return *this; } // conversion operators must not be explicit or it defeats the point // of this class (ease of use, transparency). @@ -42,7 +62,7 @@ namespace util { // explicitly disable equality with unequal types or tags. this // prevents the conversion operator getting invoked and falsely - // allowing equality with different tags. + // allowing equality with different types or tags. template std::enable_if_t::value || !std::is_same::value,bool> operator== (const strongdef &rhs) = delete;