我有BigNum
课程。
我需要实现什么样的方法,构造函数等才能产生预期效果(如评论中)?
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
答案 0 :(得分:3)
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
对于这些,您需要非显式构造函数,它们将接受除bool
和char
之外的整数类型。您可以编写一整套完整的重载,如std::to_string的重载。请注意,对于小于int
的类型,您不需要重载,因为它们可以毫无歧义地提升为int
或unsigned int
。您可以将所有这些调用委托给long long
和unsigned long long
版本,并且只实现这两个版本。
// 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);
要禁用bool
和char
,您可以删除这些构造函数。那么你想要错误的那些行会出错。如果你不这样做,他们只会升级到int
,所以不会有错误。
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;
另一种方法是定义一个接受任何整数类型的构造函数模板,然后像以前一样为bool
和char
定义其他已删除的重载。这避免了必须编写多个实现。
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
为此你需要赋值运算符。你可能只想在这里玩同样的游戏。
// 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;
答案 1 :(得分:2)
实际上并非如此简单,因为bool
和char
将隐式转换为其他整数类型。但我已经做到了:
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) {}
};
答案 2 :(得分:0)
我建议使用模板和 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");
// ...
}
};
您可以类似地为operator=
。
答案 3 :(得分:-1)
鉴于此
a = 42; //compiles
您还需要一个赋值运算符。 简单的例子:
BigNum& operator=(const int n)
{
// relevant stuff here...
return *this;
}