C++模板<Operator>
C++ Template<Operator>
我目前正在建立一个bigint类,并且在超载运算符时&amp; |和 ^,所有这些都具有相似的函数语法,我想知道是否可以像这样模拟操作员自己:
template<operator K>
BigInt operator K( const BigInt& a, const BigInt& b )
{
BigInt Result = 0;
uint64_t Max = max(a.GetSize() , b.GetSize()) /* max(a,b) is defined outside */
for (uint64_t n=0; n < Max; n++)
{
Result[n] = a[n] K b[N];
}
return Result;
}
[n]以(二进制(的n数字返回bool,然后将其应用于操作员&amp;,|^,这样我就不会写3个操作员过载,这些过载与2个字母相同。
我知道这种语法不起作用,但是我问是否有任何方法可以做您可能期望的语法要做的事情:by&amp;,|或 ^,并且仅在代码中编写(a&amp; b(时。
如果在这里有所帮助是我对课堂的定义:
class BigInt
{
private:
vector<bool> num;
public:
/* Constructors */
BigInt();
template<class T> BigInt(T);
/* Class Methods */
void RLZ(); /* Remove Leading Zeroes */
uint64_t GetSize() const;
void print();
/* Operator Overloads */
std::vector<bool>::reference operator[] (uint64_t);
bool operator[] (uint64_t) const;
BigInt& operator=(const BigInt&);
};
一个想法是定义在操作员函数上模板上的助手函数(因为您无法在操作员本身上模板(,然后实例化模板在适当的Bigint运营商的定义中。例如:
template <class OperatorFn>
BigInt bitwiseOperator(const BigInt& a, const BigInt& b) const
{
BigInt Result = 0;
uint64_t Max = max(a.GetSize(), b.GetSize());
for (uint64_t n=0; n < Max; n++)
{
Result[n] = OperatorFn{}(a[n], b[N]);
}
return Result;
}
BigInt operator&(const BigInt& a, const BigInt& b) const { return bitwiseOperator<std::bit_and<bool>>(a, b); }
BigInt operator|(const BigInt& a, const BigInt& b) const { return bitwiseOperator<std::bit_or<bool>>(a, b); }
BigInt operator^(const BigInt& a, const BigInt& b) const { return bitwiseOperator<std::bit_xor<bool>>(a, b); }
我会写这篇:
template<class F>
BigInt& bitwiseReplace( F&& f, BigInt& lhs, BigInt const& rhs ) {
auto max = (std::max)(lhs.GetSize(), rhs.GetSize());
for (uint64_t i=0; i < max; ++i)
lhs[i] = f( lhs[i], rhs[i] );
return lhs;
}
请注意,我通过参考将lhs
进行修改。这是故意的。这对应于&=
和|=
。
template<class F>
BigInt bitwiseCreate( F&& f, BigInt lhs, BigInt const& rhs ) {
bitwiseReplace( std::forward<F>(f), lhs, rhs );
return lhs;
}
这对应于+
或|
。
在您的班级中:
BigInt& operator=(const BigInt&)=default;
BigInt& operator=(BigInt&&)=default;
BigInt(const BigInt&)=default;
BigInt(BigInt&&)=default;
在这里做正确的事情,有默认的移动/复制分配/构造。
现在您只需要写一行:
BigInt& operator&=( BigInt const& rhs ) { return bitwiseReplace( std::bit_and<bool>{}, *this, rhs ); }
BigInt& operator|=( BigInt const& rhs ) { return bitwiseReplace( std::bit_or<bool>{}, *this, rhs ); }
friend BigInt operator&( BigInt lhs, BigInt const& rhs ) { return bitwiseCreate( std::bit_and<bool>{}, std::move(lhs), rhs ); }
friend BigInt operator|( BigInt lhs, BigInt const& rhs ) { return bitwiseCreate( std::bit_or<bool>{}, std::move(lhs), rhs ); }
这需要少量的胶水代码。
用价值占据的左侧意味着
auto r = a | b | c;
是有效的 - a | b
的结果被移动(实际上是浮动(,没有执行任何副本。
另一个优点是您可以用std::vector<uint32_t>
替换std::vector<bool>
。只需编写wordwiseReplace
和wordwiseCreate
,它以非常相似的方式在每个uint32_t
上运行并在每个CC_12上运行。
您可以使用一些其他工作,甚至可以以这种方式实现+
和-
。该功能对象可以携带随身携带信息。您必须检查末端是否有溢流/下底并进行调整。
*
和/
将需要更多的工作。
相关文章:
- 为什么 std::optional::operator=(U&&) 要求你是非标量类型?
- 'operator='已弃用:改用 QDir::setPath()
- EASTL矢量<向量<int>>连续的
- 过载'operator new'如何导致无限循环?
- 与'operator='不匹配(操作数类型'String'且"void")
- SegFault 同时使用 std::string::operator+= 和函数作为参数
- 处理"no operator found"
- 如何编写 operator= 用于使用虚拟方法与非平凡成员的匿名联合
- 运算符重载:"operator+"必须采用零个或一个参数
- 使用 operator() 扩展 Eigen::EigenBase
- 错误消息:使用"string* +="后"no match for 'operator+='"
- 有没有办法修改'operator->',以便'z->im'返回复数的虚部
- "operator +="行为异常的定义
- C++ "error: use of overloaded operator '*' is ambiguous"似乎只有一场比赛
- 错误:二进制'operator*' 'float'和'float[0]'类型的操作数无效
- 在 Eclipse: "error: no match for 'operator='" 中获取错误消息
- 为什么 operator() 处的指针成员不起作用?
- 为什么 string_view::operator== 按值接受参数
- "operator()"在重载运算符方法中是什么意思,在priority_queue(STL)中用作C++中的比较器?
- Valarray 切片数组与 'operator*' 不匹配