类型转换、显式构造函数等
Type conversion, explicit constructors etc
我有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
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;
实际上并不那么简单,因为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) {}
};
我建议使用模板和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=
进行类似的操作。
给定此
a = 42; //compiles
您还需要一个赋值运算符。简单示例:
BigNum& operator=(const int n)
{
// relevant stuff here...
return *this;
}
相关文章:
- 构造函数和转换运算符之间的重载解析
- C++无效的函数类型转换
- 元组尺寸默认构造函数及其转换为std :: size_t
- C++ 03 类模板 这是转换构造函数还是转换运算符?以及如何声明解决此问题的方法
- 是否可以将一种函数类型转换为另一种采用相同参数但返回类型不同的函数类型
- 调用构造函数或转换
- 需要构造函数/析构函数/类型转换错误
- 使用构造函数自动转换
- static_cast转换构造函数与转换运算符
- 构造函数和转换
- C++ - 打印地图<结构,结构,构造函数>类型
- 错误:从"<未解析的重载函数类型>"转换为非标量类型
- 有没有一种干净的方法可以将 C# 'params object[]' 构造函数参数转换为C++构造函数?
- 混淆了复制构造函数和转换构造函数
- C++11:在按值传递参数初始化时转换构造函数和转换函数之间的歧义
- 继承构造函数+非默认构造函数类型的类内初始化失败
- 特征日志和exp函数类型转换错误
- c++ python构造函数类型错误(可能的命名空间问题)
- 构造函数的转换不适用于运算符重载
- 具有构造函数类型转换和转换操作符的转换序列