使用自定义整数 class 作为数组中的索引 (c++)
Use custom integer class as index in an array (c++)
我已经为 c++ 写了 BigInt
class,但是我无法使用 class 作为数组的索引。
示例:
int main() {
int array[5] = {4, 6, 2, 9, 0};
BigInt index = 1;
std::cout << array[index] << std::endl;
}
这导致:
error: no match for 'operator[]' (operand types are 'int [5]' and 'BigInt')
cout << array[index] << endl;
^
我尝试实现了以下功能,但无济于事。
int operator[] (BigInt &value) {
return (int) value;
}
explicit operator int() {
int result = 0;
for (auto i : digits)
result = result * 10 + i;
return result;
}
我确定当 class 本身是一个可迭代对象时会使用 operator[]
,所以这毫无意义。
explicit operator int()
有效,但仅当我将 BigInt
转换为 int
时,如 array[(int) index]
从 operator int()
中删除 explicit
效果很好,除了我不能再执行涉及 int
和 BigInt
的操作
// ...
operator int() {
int result = 0;
for (auto i : digits)
result = result * 10 + i;
return result;
}
// ...
int main() {
int array[5] = {4, 6, 2, 9, 0};
BigInt index = 1;
std::cout << array[index] << std::endl; // Works fine
std::cout << (index == 1) << std::endl; // Doesn't work
}
以上导致以下错误:
error: ambiguous overload for 'operator==' (operand types are 'BigInt' and 'int')
cout << (index == 1) << endl;
~~~~~ ^~ ~
如何克服这些错误?
谢谢!
编辑:
BigInt
class如下:
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
class BigInt {
public:
std::vector<unsigned short> digits;
bool negative;
BigInt(){
this -> digits = {0};
this -> negative = false;
}
BigInt(const BigInt &other){
this -> digits = other.digits;
this -> negative = other.negative;
}
BigInt(std::string other) {
if (other.size() == 0) {
*this = BigInt();
return;
}
std::reverse(other.begin(), other.end());
negative = false;
while (other.back() == '-') {
negative = !negative;
other.pop_back();
}
digits.clear();
for (char c : other)
digits.push_back(c - '0');
(*this).trim();
}
BigInt(const char *other) {
*this = (std::string) other;
}
template<typename T>
BigInt(const T &other) {
*this = to_std::string(other);
}
friend bool operator== (const BigInt &a, const BigInt &b) {
if (a.negative != b.negative || a.digits.size() != b.digits.size())
return false;
for (int i = 0; i < a.digits.size(); i++)
if (a.digits[i] != b.digits[i])
return false;
return true;
}
friend bool operator!= (const BigInt &a, const BigInt &b) {
return !(a == b);
}
friend bool operator< (const BigInt &a, const BigInt &b) {
if (a.negative && b.negative) return (-a) > (-b);
if (a.negative && !b.negative) return true;
if (!a.negative && b.negative) return false;
if (a.digits.size() < b.digits.size()) return true;
if (a.digits.size() > b.digits.size()) return false;
for (int i = a.digits.size() - 1; i >= 0; i--) {
if (a.digits[i] < b.digits[i]) return true;
if (a.digits[i] > b.digits[i]) return false;
}
return false;
}
friend bool operator<= (const BigInt &a, const BigInt &b) {
return !(a > b);
}
friend bool operator> (const BigInt &a, const BigInt &b) {
if (a.negative && b.negative) return (-a) < (-b);
if (!a.negative && b.negative) return true;
if (a.negative && !b.negative) return false;
if (a.digits.size() > b.digits.size()) return true;
if (a.digits.size() < b.digits.size()) return false;
for (int i = a.digits.size() - 1; i >= 0; i--) {
if (a.digits[i] > b.digits[i]) return true;
if (a.digits[i] < b.digits[i]) return false;
}
return false;
}
friend bool operator>= (const BigInt &a, const BigInt &b) {
return !(a < b);
}
friend BigInt operator+ (const BigInt &a, const BigInt &b) {
if (a.negative && b.negative) {
return -((-a) + (-b));
} else if (a.negative && !b.negative) {
return b - (-a);
} else if (!a.negative && b.negative) {
return a - (-b);
} else {
BigInt result; result.digits.clear();
int carry = 0;
for (int i = 0; i < std::max(a.digits.size(), b.digits.size()); i++) {
int sum = carry;
if (i < a.digits.size()) sum += a.digits[i];
if (i < b.digits.size()) sum += b.digits[i];
result.digits.push_back(sum % 10);
carry = sum / 10;
}
if (carry)
result.digits.push_back(carry);
result.trim();
return result;
}
}
friend BigInt operator+ (const BigInt &value) {
return value;
}
friend BigInt operator- (const BigInt &a, const BigInt &b) {
if (a.negative && b.negative) {
return b - a;
} else if (a.negative && !b.negative) {
return -((-a) + b);
} else if (!a.negative && b.negative) {
return a + (-b);
} else {
if (a < b)
return -(b - a);
BigInt result; result.digits.clear();
int carry = 0;
for (int i = 0; i < a.digits.size(); i++) {
int dif = a.digits[i] - carry;
if (i < b.digits.size()) dif -= b.digits[i];
if (dif < 0) {
dif += 10;
carry = 1;
} else {
carry = 0;
}
result.digits.push_back(dif);
}
result.trim();
return result;
}
}
friend BigInt operator- (const BigInt &value) {
BigInt result = value;
result.negative = !result.negative;
result.trim();
return result;
}
friend BigInt operator* (const BigInt &a, const BigInt &b) {
BigInt result;
for (int i = 0; i < a.digits.size(); i++) {
BigInt current; current.digits.clear();
for (int j = 0; j < i; j++)
current.digits.push_back(0);
int carry = 0;
for (int j = 0; j < b.digits.size(); j++) {
int cur_val = a.digits[i] * b.digits[j] + carry;
current.digits.push_back(cur_val % 10);
carry = cur_val / 10;
}
if (carry)
current.digits.push_back(carry);
current.trim();
result += current;
}
result.negative = a.negative ^ b.negative;
result.trim();
return result;
}
friend BigInt operator/ (const BigInt &a, const BigInt &b) {
if (b == 0)
throw std::runtime_error("Division by zero");
BigInt fa = abs(a), fb = abs(b);
BigInt result, left_over;
result.negative = a.negative ^ b.negative;
int index = fa.digits.size() - 1;
while (true) {
BigInt cur = left_over; bool first_digit = true;
while (index >= 0 && cur < fb) {
cur = cur * 10 + fa.digits[index--];
if (!first_digit) result *= 10;
first_digit = false;
}
int cur_res = 0;
while (cur >= fb)
cur -= fb, cur_res++;
left_over = cur;
result = result * 10 + cur_res;
if (index < 0)
break;
}
result.trim();
return result;
}
friend BigInt operator% (const BigInt &a, const BigInt &b) {
if (b == 0)
throw std::runtime_error("Division by zero");
BigInt fa = abs(a), fb = abs(b);
BigInt left_over;
int index = fa.digits.size() - 1;
while (true) {
BigInt cur = left_over;
while (index >= 0 && cur < fb)
cur = cur * 10 + fa.digits[index--];
while (cur >= fb)
cur -= fb;
left_over = cur;
if (index < 0)
break;
}
left_over.negative = b.negative;
left_over.trim();
return left_over;
}
friend BigInt pow(BigInt a, BigInt b) {
BigInt result = 1;
while (b) {
if (b % 2)
result = (result * a);
a *= a;
b /= 2;
}
result.trim();
return result;
}
friend BigInt pow(BigInt a, BigInt b, BigInt mod) {
BigInt result = 1;
if (mod == 0)
throw std::runtime_error("Modulo by zero");
while (b) {
if (b % 2)
result = (result * a) % mod;
a = (a * a) % mod;
b /= 2;
}
result.trim();
return result;
}
friend BigInt operator& (BigInt a, BigInt b) {
BigInt result, power = 1;
while (a > 0 && b > 0) {
if (a % 2 && b % 2)
result += power;
power <<= 1;
a >>= 1;
b >>= 1;
}
return result;
}
friend BigInt operator| (BigInt a, BigInt b) {
BigInt result, power = 1;
while (a > 0 || b > 0) {
if (a % 2 || b % 2)
result += power;
power <<= 1;
a >>= 1;
b >>= 1;
}
return result;
}
friend BigInt operator^ (BigInt a, BigInt b) {
BigInt result, power = 1;
while (a > 0 || b > 0) {
if (a % 2 != b % 2)
result += power;
power <<= 1;
a >>= 1;
b >>= 1;
}
return result;
}
friend BigInt operator<< (BigInt a, BigInt b) {return a * pow(2, b);}
friend BigInt operator>> (BigInt a, BigInt b) {return a / pow(2, b);}
BigInt operator++ () {return *this = *this + 1;}
BigInt operator-- () {return *this = *this - 1;}
BigInt operator++ (int) {BigInt result = *this; *this = *this + 1; return result;}
BigInt operator-- (int) {BigInt result = *this; *this = *this - 1; return result;}
BigInt operator+= (BigInt other) {return *(this) = *(this) + other;}
BigInt operator-= (BigInt other) {return *(this) = *(this) - other;}
BigInt operator*= (BigInt other){return *(this) = *(this) * other;}
BigInt operator/= (BigInt other){return *(this) = *(this) / other;}
BigInt operator%= (BigInt other){return *(this) = *(this) % other;}
BigInt operator&= (BigInt other){return *(this) = *(this) & other;}
BigInt operator|= (BigInt other){return *(this) = *(this) | other;}
BigInt operator^= (BigInt other){return *(this) = *(this) ^ other;}
BigInt operator<<= (BigInt other){return *(this) = *(this) << other;}
BigInt operator>>= (BigInt other){return *(this) = *(this) >> other;}
int operator[] (BigInt &value) {
return (int) value;
}
explicit operator bool() {
return *this != 0;
}
explicit operator int() {
int result = 0;
for (auto i : digits)
result = result * 10 + i;
return result;
}
friend bool operator !(const BigInt &other) {
return other == 0;
}
friend std::string to_string(const BigInt &value) {
std::string result;
if (value.negative)
result += '-';
for (int i = value.digits.size() - 1; i >= 0; i--)
result += value.digits[i] + '0';
return result;
}
friend BigInt abs(const BigInt &value) {
BigInt result = value;
result.negative = false;
return result;
}
void trim() {
while (digits.size() > 1 && digits.back() == 0)
digits.pop_back();
if (digits.size() == 1 && digits.back() == 0)
negative = false;
}
friend std::istream& operator>> (std::istream& in, BigInt &value){
std::string s; in >> s;
value = BigInt(s);
return in;
}
friend std::ostream& operator<< (std::ostream& out, const BigInt &value){
auto digits = value.digits;
if (value.negative)
out << "-";
for (auto it = digits.rbegin(); it != digits.rend(); it++)
out << *it;
return out;
}
};
一种可能的方法是仅针对另一个操作数声明标准运算符,该操作数是 class 本身中的 BigInt 对象。
然后你在BigInt中声明一个隐式转换函数成员class。
最后,您声明了自由运算符函数(在 class 之外)以对 BigInt 和 int 进行运算。那些自由函数将具有最高优先级,因为它们的参数将完全匹配并将消除任何不明确的运算符错误。
在您添加 BigInt class 之前,我已经开始编写示例代码,并且我从一个更简单的示例开始:仅正值和仅运算符 + 定义。但是编译和运行时甚至没有警告:
#include <iostream>
#include <vector>
#include <stdexcept>
/* This is a tiny multiprecision class for unsigned values.
*
* Currently only addition is implemented, between BigInt objects
* or between an unsigned value and a BigInt object
* The class in implicitely convertible to unsigned, but this throws
* if the value cannot fit into a single unsigned
*/
class BigInt {
std::vector<unsigned int> val;
public:
BigInt(unsigned i = 0) {
val.push_back(i);
}
operator unsigned() const {
if (val.size() > 1) {
throw std::overflow_error("BigInt is too big");
}
return val[0];
}
// Implementation of an addition (beware almost untested...)
BigInt operator+(const BigInt& other) const {
if (other.val.size() > val.size()) return other + *this;
BigInt tmp(*this);
unsigned carry = 0;
for (int i = 0; i < other.val.size(); i++) {
tmp.val[i] += carry + other.val[i];
if (tmp.val[i] < other.val[i] || tmp.val[i] < val[i]) {
carry = 1;
}
else {
carry = 0;
}
}
for (int i = other.val.size(); i < val.size(); i++) {
tmp.val[i] += carry;
if (0 == tmp.val[i]) {
carry = 1;
}
else {
carry = 0;
break;
}
}
if (carry) tmp.val.push_back(1);
return tmp;
}
// an auxiliary function to be used in operators
BigInt add(unsigned i) const {
// trace to make sure that this method was called...
std::cout << "add " << this->val[0] << " and " << i << '\n';
return *this + BigInt(i);
}
};
// addition operator free functions
BigInt operator+ (int i, const BigInt& b) {
return b.add(i);
}
BigInt operator+ (const BigInt& b, int i) {
return b.add(i);
}
int main() {
BigInt x(2);
x = x + 1;
x = 1 + x;
std::cout << static_cast<int>( x) << '\n';
int arr[] = { 1, 2, 3, 4, 5, 6 };
std::cout << arr[x] << '\n';
}
此代码按预期显示(包括 Clang 11 和 MSVC2022):
add 2 and 1
add 3 and 1
4
5
我已经为 c++ 写了 BigInt
class,但是我无法使用 class 作为数组的索引。
示例:
int main() {
int array[5] = {4, 6, 2, 9, 0};
BigInt index = 1;
std::cout << array[index] << std::endl;
}
这导致:
error: no match for 'operator[]' (operand types are 'int [5]' and 'BigInt')
cout << array[index] << endl;
^
我尝试实现了以下功能,但无济于事。
int operator[] (BigInt &value) {
return (int) value;
}
explicit operator int() {
int result = 0;
for (auto i : digits)
result = result * 10 + i;
return result;
}
我确定当 class 本身是一个可迭代对象时会使用 operator[]
,所以这毫无意义。
explicit operator int()
有效,但仅当我将 BigInt
转换为 int
时,如 array[(int) index]
从 operator int()
中删除 explicit
效果很好,除了我不能再执行涉及 int
和 BigInt
// ...
operator int() {
int result = 0;
for (auto i : digits)
result = result * 10 + i;
return result;
}
// ...
int main() {
int array[5] = {4, 6, 2, 9, 0};
BigInt index = 1;
std::cout << array[index] << std::endl; // Works fine
std::cout << (index == 1) << std::endl; // Doesn't work
}
以上导致以下错误:
error: ambiguous overload for 'operator==' (operand types are 'BigInt' and 'int')
cout << (index == 1) << endl;
~~~~~ ^~ ~
如何克服这些错误?
谢谢!
编辑:
BigInt
class如下:
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
class BigInt {
public:
std::vector<unsigned short> digits;
bool negative;
BigInt(){
this -> digits = {0};
this -> negative = false;
}
BigInt(const BigInt &other){
this -> digits = other.digits;
this -> negative = other.negative;
}
BigInt(std::string other) {
if (other.size() == 0) {
*this = BigInt();
return;
}
std::reverse(other.begin(), other.end());
negative = false;
while (other.back() == '-') {
negative = !negative;
other.pop_back();
}
digits.clear();
for (char c : other)
digits.push_back(c - '0');
(*this).trim();
}
BigInt(const char *other) {
*this = (std::string) other;
}
template<typename T>
BigInt(const T &other) {
*this = to_std::string(other);
}
friend bool operator== (const BigInt &a, const BigInt &b) {
if (a.negative != b.negative || a.digits.size() != b.digits.size())
return false;
for (int i = 0; i < a.digits.size(); i++)
if (a.digits[i] != b.digits[i])
return false;
return true;
}
friend bool operator!= (const BigInt &a, const BigInt &b) {
return !(a == b);
}
friend bool operator< (const BigInt &a, const BigInt &b) {
if (a.negative && b.negative) return (-a) > (-b);
if (a.negative && !b.negative) return true;
if (!a.negative && b.negative) return false;
if (a.digits.size() < b.digits.size()) return true;
if (a.digits.size() > b.digits.size()) return false;
for (int i = a.digits.size() - 1; i >= 0; i--) {
if (a.digits[i] < b.digits[i]) return true;
if (a.digits[i] > b.digits[i]) return false;
}
return false;
}
friend bool operator<= (const BigInt &a, const BigInt &b) {
return !(a > b);
}
friend bool operator> (const BigInt &a, const BigInt &b) {
if (a.negative && b.negative) return (-a) < (-b);
if (!a.negative && b.negative) return true;
if (a.negative && !b.negative) return false;
if (a.digits.size() > b.digits.size()) return true;
if (a.digits.size() < b.digits.size()) return false;
for (int i = a.digits.size() - 1; i >= 0; i--) {
if (a.digits[i] > b.digits[i]) return true;
if (a.digits[i] < b.digits[i]) return false;
}
return false;
}
friend bool operator>= (const BigInt &a, const BigInt &b) {
return !(a < b);
}
friend BigInt operator+ (const BigInt &a, const BigInt &b) {
if (a.negative && b.negative) {
return -((-a) + (-b));
} else if (a.negative && !b.negative) {
return b - (-a);
} else if (!a.negative && b.negative) {
return a - (-b);
} else {
BigInt result; result.digits.clear();
int carry = 0;
for (int i = 0; i < std::max(a.digits.size(), b.digits.size()); i++) {
int sum = carry;
if (i < a.digits.size()) sum += a.digits[i];
if (i < b.digits.size()) sum += b.digits[i];
result.digits.push_back(sum % 10);
carry = sum / 10;
}
if (carry)
result.digits.push_back(carry);
result.trim();
return result;
}
}
friend BigInt operator+ (const BigInt &value) {
return value;
}
friend BigInt operator- (const BigInt &a, const BigInt &b) {
if (a.negative && b.negative) {
return b - a;
} else if (a.negative && !b.negative) {
return -((-a) + b);
} else if (!a.negative && b.negative) {
return a + (-b);
} else {
if (a < b)
return -(b - a);
BigInt result; result.digits.clear();
int carry = 0;
for (int i = 0; i < a.digits.size(); i++) {
int dif = a.digits[i] - carry;
if (i < b.digits.size()) dif -= b.digits[i];
if (dif < 0) {
dif += 10;
carry = 1;
} else {
carry = 0;
}
result.digits.push_back(dif);
}
result.trim();
return result;
}
}
friend BigInt operator- (const BigInt &value) {
BigInt result = value;
result.negative = !result.negative;
result.trim();
return result;
}
friend BigInt operator* (const BigInt &a, const BigInt &b) {
BigInt result;
for (int i = 0; i < a.digits.size(); i++) {
BigInt current; current.digits.clear();
for (int j = 0; j < i; j++)
current.digits.push_back(0);
int carry = 0;
for (int j = 0; j < b.digits.size(); j++) {
int cur_val = a.digits[i] * b.digits[j] + carry;
current.digits.push_back(cur_val % 10);
carry = cur_val / 10;
}
if (carry)
current.digits.push_back(carry);
current.trim();
result += current;
}
result.negative = a.negative ^ b.negative;
result.trim();
return result;
}
friend BigInt operator/ (const BigInt &a, const BigInt &b) {
if (b == 0)
throw std::runtime_error("Division by zero");
BigInt fa = abs(a), fb = abs(b);
BigInt result, left_over;
result.negative = a.negative ^ b.negative;
int index = fa.digits.size() - 1;
while (true) {
BigInt cur = left_over; bool first_digit = true;
while (index >= 0 && cur < fb) {
cur = cur * 10 + fa.digits[index--];
if (!first_digit) result *= 10;
first_digit = false;
}
int cur_res = 0;
while (cur >= fb)
cur -= fb, cur_res++;
left_over = cur;
result = result * 10 + cur_res;
if (index < 0)
break;
}
result.trim();
return result;
}
friend BigInt operator% (const BigInt &a, const BigInt &b) {
if (b == 0)
throw std::runtime_error("Division by zero");
BigInt fa = abs(a), fb = abs(b);
BigInt left_over;
int index = fa.digits.size() - 1;
while (true) {
BigInt cur = left_over;
while (index >= 0 && cur < fb)
cur = cur * 10 + fa.digits[index--];
while (cur >= fb)
cur -= fb;
left_over = cur;
if (index < 0)
break;
}
left_over.negative = b.negative;
left_over.trim();
return left_over;
}
friend BigInt pow(BigInt a, BigInt b) {
BigInt result = 1;
while (b) {
if (b % 2)
result = (result * a);
a *= a;
b /= 2;
}
result.trim();
return result;
}
friend BigInt pow(BigInt a, BigInt b, BigInt mod) {
BigInt result = 1;
if (mod == 0)
throw std::runtime_error("Modulo by zero");
while (b) {
if (b % 2)
result = (result * a) % mod;
a = (a * a) % mod;
b /= 2;
}
result.trim();
return result;
}
friend BigInt operator& (BigInt a, BigInt b) {
BigInt result, power = 1;
while (a > 0 && b > 0) {
if (a % 2 && b % 2)
result += power;
power <<= 1;
a >>= 1;
b >>= 1;
}
return result;
}
friend BigInt operator| (BigInt a, BigInt b) {
BigInt result, power = 1;
while (a > 0 || b > 0) {
if (a % 2 || b % 2)
result += power;
power <<= 1;
a >>= 1;
b >>= 1;
}
return result;
}
friend BigInt operator^ (BigInt a, BigInt b) {
BigInt result, power = 1;
while (a > 0 || b > 0) {
if (a % 2 != b % 2)
result += power;
power <<= 1;
a >>= 1;
b >>= 1;
}
return result;
}
friend BigInt operator<< (BigInt a, BigInt b) {return a * pow(2, b);}
friend BigInt operator>> (BigInt a, BigInt b) {return a / pow(2, b);}
BigInt operator++ () {return *this = *this + 1;}
BigInt operator-- () {return *this = *this - 1;}
BigInt operator++ (int) {BigInt result = *this; *this = *this + 1; return result;}
BigInt operator-- (int) {BigInt result = *this; *this = *this - 1; return result;}
BigInt operator+= (BigInt other) {return *(this) = *(this) + other;}
BigInt operator-= (BigInt other) {return *(this) = *(this) - other;}
BigInt operator*= (BigInt other){return *(this) = *(this) * other;}
BigInt operator/= (BigInt other){return *(this) = *(this) / other;}
BigInt operator%= (BigInt other){return *(this) = *(this) % other;}
BigInt operator&= (BigInt other){return *(this) = *(this) & other;}
BigInt operator|= (BigInt other){return *(this) = *(this) | other;}
BigInt operator^= (BigInt other){return *(this) = *(this) ^ other;}
BigInt operator<<= (BigInt other){return *(this) = *(this) << other;}
BigInt operator>>= (BigInt other){return *(this) = *(this) >> other;}
int operator[] (BigInt &value) {
return (int) value;
}
explicit operator bool() {
return *this != 0;
}
explicit operator int() {
int result = 0;
for (auto i : digits)
result = result * 10 + i;
return result;
}
friend bool operator !(const BigInt &other) {
return other == 0;
}
friend std::string to_string(const BigInt &value) {
std::string result;
if (value.negative)
result += '-';
for (int i = value.digits.size() - 1; i >= 0; i--)
result += value.digits[i] + '0';
return result;
}
friend BigInt abs(const BigInt &value) {
BigInt result = value;
result.negative = false;
return result;
}
void trim() {
while (digits.size() > 1 && digits.back() == 0)
digits.pop_back();
if (digits.size() == 1 && digits.back() == 0)
negative = false;
}
friend std::istream& operator>> (std::istream& in, BigInt &value){
std::string s; in >> s;
value = BigInt(s);
return in;
}
friend std::ostream& operator<< (std::ostream& out, const BigInt &value){
auto digits = value.digits;
if (value.negative)
out << "-";
for (auto it = digits.rbegin(); it != digits.rend(); it++)
out << *it;
return out;
}
};
一种可能的方法是仅针对另一个操作数声明标准运算符,该操作数是 class 本身中的 BigInt 对象。
然后你在BigInt中声明一个隐式转换函数成员class。
最后,您声明了自由运算符函数(在 class 之外)以对 BigInt 和 int 进行运算。那些自由函数将具有最高优先级,因为它们的参数将完全匹配并将消除任何不明确的运算符错误。
在您添加 BigInt class 之前,我已经开始编写示例代码,并且我从一个更简单的示例开始:仅正值和仅运算符 + 定义。但是编译和运行时甚至没有警告:
#include <iostream>
#include <vector>
#include <stdexcept>
/* This is a tiny multiprecision class for unsigned values.
*
* Currently only addition is implemented, between BigInt objects
* or between an unsigned value and a BigInt object
* The class in implicitely convertible to unsigned, but this throws
* if the value cannot fit into a single unsigned
*/
class BigInt {
std::vector<unsigned int> val;
public:
BigInt(unsigned i = 0) {
val.push_back(i);
}
operator unsigned() const {
if (val.size() > 1) {
throw std::overflow_error("BigInt is too big");
}
return val[0];
}
// Implementation of an addition (beware almost untested...)
BigInt operator+(const BigInt& other) const {
if (other.val.size() > val.size()) return other + *this;
BigInt tmp(*this);
unsigned carry = 0;
for (int i = 0; i < other.val.size(); i++) {
tmp.val[i] += carry + other.val[i];
if (tmp.val[i] < other.val[i] || tmp.val[i] < val[i]) {
carry = 1;
}
else {
carry = 0;
}
}
for (int i = other.val.size(); i < val.size(); i++) {
tmp.val[i] += carry;
if (0 == tmp.val[i]) {
carry = 1;
}
else {
carry = 0;
break;
}
}
if (carry) tmp.val.push_back(1);
return tmp;
}
// an auxiliary function to be used in operators
BigInt add(unsigned i) const {
// trace to make sure that this method was called...
std::cout << "add " << this->val[0] << " and " << i << '\n';
return *this + BigInt(i);
}
};
// addition operator free functions
BigInt operator+ (int i, const BigInt& b) {
return b.add(i);
}
BigInt operator+ (const BigInt& b, int i) {
return b.add(i);
}
int main() {
BigInt x(2);
x = x + 1;
x = 1 + x;
std::cout << static_cast<int>( x) << '\n';
int arr[] = { 1, 2, 3, 4, 5, 6 };
std::cout << arr[x] << '\n';
}
此代码按预期显示(包括 Clang 11 和 MSVC2022):
add 2 and 1
add 3 and 1
4
5