Reputation: 188
I have BigNum
class.
What exactly methods, constructors etc. I need to implement to have desired effect (like in comments)?
class BigNum {
//...?
};
BigNum a = 1; // compiles
a = 42; // compiles
BigNum b = 1L; // compiles
BigNum c = 1U; // compiles
BigNum d = 1UL; // compiles
BigNum e = true; // doesn't compile
BigNum f = '1'; // doesn't compile
Upvotes: 0
Views: 77
Reputation: 2379
I would recommend using a template and std::static_assert:
struct BigNum {
template <typename Int> BigNum(Int val)
{
std::static_assert(std::is_integral<Int>::value,"must be integral");
std::static_assert(!std::is_same<Int,bool>::value,"can not be bool");
std::static_assert(!std::is_same<Int,char>::value,"can not be char");
// ...
}
};
You can do it analogously for the operator=
.
Upvotes: 0
Reputation: 19607
Not so simple, actually, because bool
and char
will implicitly convert to other integral types. But I've made this:
class BigNum {
public:
template <
typename T,
typename = typename std::enable_if<std::is_integral<T>::value &&
!std::is_same<T, bool>::value && !std::is_same<T, char>::value>::type>
BigNum(T) {}
};
Upvotes: 2
Reputation: 2890
Given this
a = 42; //compiles
you also need an assignment operator. Simple example:
BigNum& operator=(const int n)
{
// relevant stuff here...
return *this;
}
Upvotes: -1
Reputation: 119184
BigNum a = 1; //compiles BigNum b = 1L; //compiles BigNum c = 1U; //compiles BigNum d = 1UL; //compiles BigNum e = true; //doesn't compile BigNum f = '1'; //doesn't compile
For these you need non-explicit constructors that will accept integral types except bool
and char
. You can write a full set of integral overloads like those of std::to_string. Note that you don't need overloads for types smaller than int
because they can be promoted to either int
or unsigned int
without ambiguity. You can delegate all of these calls to the long long
and unsigned long long
versions and only implement those two.
// remember to define these
BigNum(unsigned long long x);
BigNum(long long x);
BigNum(unsigned long x);
BigNum(long x);
BigNum(unsigned int x);
BigNum(int x);
To disable bool
and char
, you can delete those constructors. Then there will be an error for those lines you want errors for. If you don't do this, they'll just get promoted to int
so there won't be an error.
BigNum(bool x) = delete;
BigNum(char x) = delete;
// you might also want to delete these:
// BigNum(char16_t x) = delete;
// BigNum(char32_t x) = delete;
Another approach is to define one constructor template that accepts any integral type, then define additional deleted overloads for bool
and char
as before. This avoids having to write multiple implementations.
template <typename Integral, typename = std::enable_if_t<std::is_integral<Integral>::value>>
BigNum(Integral i);
BigNum(bool b) = delete;
BigNum(char c) = delete;
a = 42; //compiles
For this you need assignment operators. You probably just want to play the same game here.
// remember to define these
BigNum& operator=(unsigned long long x);
BigNum& operator=(long long x);
// you can delegate these to the above
BigNum& operator=(unsigned long x);
BigNum& operator=(long x);
BigNum& operator=(unsigned int x);
BigNum& operator=(int x);
BigNum& operator=(bool x) = delete;
BigNum& operator=(char x) = delete;
// BigNum& operator=(char16_t x) = delete;
// BigNum& operator=(char32_t x) = delete;
Upvotes: 3