I have a class to store big unsigned numbers and I'd like to allow user to create object using types such as long long
, int
, unsigned int
and so on and also from string
. I created a constructor BigNumber(const unsigned long long)
and BigNumber(const std::string)
but I want to disallow user to use constructions like: BigNumber('a')
or BigNumber(true)
. I heard about explicit
so I decided to write in my class definition following lines:
explicit BigNumber(const bool) = delete;
explicit BigNumber(const char) = delete;
Unfortunately when I want to create object like: BigNumber x(1)
or BigNumber("1234")
I get error that call of overloaded constructor is ambiguous. I didn't get this message before I wrote these lines with explicit
. How to solve this problem?
You can achieve this using a template:
template<typename T,
typename = typename std::enable_if<
std::is_integral<T>::value
&& !std::is_same<char, T>::value
&& !std::is_same<bool, T>::value>::type>
explicit BigNumber(T const n);
This constructor can't be called with bool
s or char
s.
You can use a similar trick as when making classes non-copyable.
struct A {
explicit A(int) { ... }
explicit A(std::string) { ... }
// prevent any other types
template <typename T> A(T) = delete;
};
This will require the argument to A's constructor to be exactly int
or string
.
A a1{1}; // OK
A a2{std::string("foobar")}; // OK
A a3(1L); // Error: use of deleted function 'A::A(T) [with T = long int]'
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With