Last active
September 1, 2020 23:46
-
-
Save ktbarrett/4a7e994d66d9d94acd2faa13cc615f10 to your computer and use it in GitHub Desktop.
It works! User defined conversion constructors
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Library code | |
#include <stdexcept> | |
#include <type_traits> | |
#include <utility> | |
namespace library { | |
template <typename T> | |
struct to_positive { | |
static const bool exists = false; | |
// can't define this here since Positive would have to be fully defined | |
// static Positive convert(T const&) { ... } | |
}; | |
class Positive { | |
public: | |
using storage_type = int; | |
Positive(storage_type const& value) | |
: value_(value) | |
{ | |
if (value_ <= 0) { | |
throw std::range_error("Value must be positive (> 0)"); | |
} | |
} | |
// here we use the user defined conversion to define a generic | |
// conversion constructor, implicit or explicit is up to you | |
// perhaps you could even add that as a parameter to the conversion | |
// template! | |
template < | |
typename Convertible, | |
std::enable_if_t<to_positive<Convertible>::exists, int> = 0 | |
> | |
Positive(Convertible const& value) | |
: Positive(to_positive<Convertible>::convert(value)) | |
{ | |
} | |
storage_type const& value() const noexcept { return value_; } | |
private: | |
storage_type value_ {0}; | |
}; | |
} | |
// User code | |
#include <string> | |
// define conversion for user type using a specialization of | |
// to_positive struct | |
template <> | |
struct library::to_positive<std::string> | |
{ | |
static const bool exists = true; | |
static Positive convert(std::string const& s) | |
{ | |
return Positive(std::stol(s)); | |
} | |
}; | |
namespace user { | |
using library::Positive; | |
using namespace std::string_literals; | |
void use() | |
{ | |
auto p = Positive("567"s); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment