[英]const struct object access member functions (and an operator overloading question)
I tried to overload the <<
operator for my custom struct
, but encountered error C2662
, code as follows:我试图为我的自定义struct
重载<<
运算符,但遇到error C2662
,代码如下:
struct HP{
int max_hp;
int hp;
HP(int max_hp){
this->max_hp=max_hp;
this->hp=max_hp;
}
// this const declarative doesn't support const HP& obj argument
const string repr(){
stringstream hp_stats;
hp_stats << this->hp << "/" << this->max_hp;
return hp_stats.str();
}
// This is fine with const HP& obj argument
const string repr(){
stringstream hp_stats;
hp_stats << this->hp << "/" << this->max_hp;
return hp_stats.str();
}
};
// would cause error C2662
ostream& operator<<(ostream& out, const HP& obj){
out<<obj.repr();
return out;
}
I've found that this is because the implicitly access of this
pointer, and const
attempts to convert *this
into const *this
and thus fails.我发现这是因为this
指针的隐式访问,并且const
尝试将*this
转换为const *this
并因此失败。 But as I changed from const string repr()
to string repr() const
, it magically worked and compiled successfully.但是当我从const string repr()
更改为string repr() const
时,它神奇地工作并成功编译。
What's the difference between a const T func(){}
and T func() const
, which makes a const struct
object invoking feasible? const T func(){}
和T func() const
有什么区别,这使得 const struct
object 调用可行?
I read it on cppreference.com, but still unsure why << overloading has to be declared outside a class scope.我在 cppreference.com 上阅读了它,但仍然不确定为什么必须在 class scope 之外声明 << 重载。
Suppose I have repr()
member function for struct HP
, struct Shield
, etc. I tried to make the << overloading a template function, but it turns that I am overloading << at global scope.假设我有repr()
成员 function 用于struct HP
, struct Shield
等。我试图使 << 重载模板 function,但事实证明我正在重载 << 在全局 Z351A1FD140BEABEF8 Can I specify the T
I am about to apply, OR apply the overloading across several classes with same member function, WITHOUT classes defined under one base class?我可以指定我将要应用的T
,或者在具有相同成员 function 的多个类中应用重载,而没有在一个基础 class 下定义类吗?
// complier thinks such overloading is global on <<
template <typename T>
ostream& operator<<(ostream& out, const T& obj){
out<<obj.repr();
return out;
}
const T func() {}
means that the return type is const T
and the function might mutate the object. const T func() {}
表示返回类型是const T
,并且 function 可能会改变 object。 Whereas, T func() const {}
means that the return type is non-const but the object is unaltered ( const
).而T func() const {}
表示返回类型是非常量,但 object 未更改( const
)。 You can also have both or neither const
.您也可以同时拥有或不拥有const
。
It doesn't have to be declared outside the class, it can be declared inside as a friend
(non-member) function.它不必在 class 之外声明,它可以在内部声明为friend
(非成员)function。 That works here as well.这也适用于这里。 However, for a member function: since operator<<()
's first parameter is ostream&
, you could only declare it in ostream
and not HP
, which won't work.但是,对于成员 function:由于operator<<()
的第一个参数是ostream&
,您只能在ostream
而不是HP
中声明它,这将不起作用。 Remember, member operators are like *this
as the first argument of non-member operators.请记住,成员运算符就像*this
作为非成员运算符的第一个参数。
Yes, you can do this.是的,你可以这样做。 The easiest is to delegate to a common print function;最简单的就是委托给一个共同的印刷品 function; the more elegant way is to use std::enable_if
, eg:更优雅的方法是使用std::enable_if
,例如:
template <typename T>
std::enable_if_v<std::is_same_v<T, HP> || std::is_same_v<t, Shield>, ostream&>
operator<<(ostream& out, const T& obj)
{
out<<obj.repr();
return out;
}
You can also write the conditions as a template and then re-use it:您还可以将条件编写为模板,然后重新使用它:
template<typename T>
using is_printable_v = std::is_same_v<T, HP> || std::is_same_v<T, Shield>;
template <typename T>
std::enable_if_v<is_printable_v<T>>, ostream&>
operator<<(ostream& out, const T& obj) { ... }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.