我试图在模板结构xpair
template <typename First, typename Second>
struct xpair {
First first{};
Second second{};
xpair(){}
xpair (const First& first, const Second& second):
first(first), second(second) {}
xpair& operator= (const xpair& that) {
cout << "*this = " << *this << " " << "that = " << that << endl;
cout << "use operator = " << endl;
*this = that;
return *this;
}
};
但是当我用
测试这段代码时using commend = string;
using str_str_pair = xpair<string, string>;
using commend_pair = xpair<commend, str_str_pair>;
commend_pair cmd_pair;
str_str_pair str_pair("a", "1");
commend cmd("comment");
cmd_pair.first = cmd;
cmd_pair.second = str_pair;
它给了我无限的输出
use operator =
*this = {,} that = {a,1}
use operator =
*this = {,} that = {a,1}
use operator =
*this = {,} that = {a,1}
use operator =
*this = {,} that = {a,1}
为什么?
答案 0 :(得分:3)
它给了我无限的输出
那是为什么?
因为您已根据自身定义了该功能,请参阅以下代码注释。
xpair& operator= (const xpair& that)
{
cout << "*this = " << *this << " " << "that = " << that << endl;
cout << "use operator = " << endl;
// Here you're asking for `this` (i.e., an `xpair` type) to be assigned
// a `that` (i.e., another `xpair` type) using the `operator=` which is
// the function currently being implemented/defined. A function calling
// itself is recursion and there is no stopping condition so it will
// continue infinitely.
*this = that;
return *this;
}
相反,您的操作应使用this
实例的数据成员设置that
实例的数据成员。
xpair& operator= (const xpair& that)
{
cout << "*this = " << *this << " " << "that = " << that << endl;
cout << "use operator = " << endl;
first = that.first;
second = that.second;
return *this;
}
答案 1 :(得分:2)
你的行
*this = that;
也是一个赋值,带有两个参数。两者都是xpair<First,Second>
,因此它再次调用相同的运算符。
您可能想要做的是:
this->first = that.first;
this->second = that.second;
调用First
和Second
的赋值运算符。
答案 2 :(得分:2)
正如其他人所说,您的问题是operator=
致电您的operator=
。这会导致无限递归。
但是,我会争论不同的实现:
添加:
template<class Self,
class=std::enable_if_t<std::is_same<std::decay_t<Self>, xpair>{}>
>
friend auto tieme(Self&& self) {
return std::forward_as_tuple(
std::forward<Self>(self).first,
std::forward<Self>(self).second
);
}
你身体的一部分。 enable_if_t的东西有点模糊,但它确保只在真正的xpairs上调用这个自由函数。
现在你的operator =只是:
xpair& operator= (const xpair& that) {
tieme(*this)=tieme(that);
return *this;
}
这很好,因为你不必重复两次元素的顺序。
但它并不止于此。
friend bool operator<(const xpair& lhs, const xpair& rhs) {
return tieme(lhs) < tieme(rhs);
}
同样的技术可以让你编写一堆其他运算符。任何曾经在<
样板中遇到错误的人都会明白上述情况很好。
移动分配?
xpair& operator= (xpair&& that) {
tieme(*this)=tieme(std::move(that));
return *this;
}
交换?
friend void swap(xpair& lhs, xpair& rhs) {
std::swap( tieme(lhs), tieme(rhs) );
}
它会扩展 - 向tieme
添加更多内容,并由所有其他方法自动处理。