【发布时间】:2015-01-12 10:40:03
【问题描述】:
我想找到最大值Foo 并在其上调用inc(),这是一个非常量方法。当然,在找到最大值时,我不想创建任何副本或移动,即我不想要Foo foo = std::max(foo1, foo2)。我尝试编写自己的最大值,而 g++ 坚持我返回一个 const&。
#include <iostream>
class Foo
{
public:
Foo(int x) : x_(x) { std::cout << "const" << std::endl; }
Foo(const Foo& foo) : x_(foo.x_) { std::cout << "copy const" << std::endl; }
Foo(Foo&& foo) : x_(foo.x_) { std::cout << "move const" << std::endl; }
bool operator< (const Foo& foo) const { return x_ < foo.x_; }
bool operator> (const Foo& foo) const { return x_ > foo.x_; }
void inc() { ++x_; }
int x_;
};
/*
* Doesn't compile. Must return const T& or must accept non-const T&
*
template<typename T>
inline T& my_max(const T& f1, const T& f2)
{
return f1 > f2 ? f1 : f2;
}
*
*/
int main()
{
Foo foo1(6);
Foo foo2(7);
Foo& foo = std::max(foo1, foo2); //Doesn't compile. Must be const Foo&. But then next line fails
foo.inc();
std::cout << foo.x_ << std::endl;
return 0;
}
【问题讨论】:
-
它返回一个 const 引用以避免不必要的复制,因为它早于右值引用和移动语义。如果今天创建它,它可能会有不同的定义,例如open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2199.html
-
另一种选择是添加
Foo copy() const& { return *this; },这样你就可以写std::max(fooA,fooB).copy().inc();。有时复制构造函数没有名字是一件很痛苦的事情。 -
您已经知道一个答案:您的评论说 "...或者必须接受非常量 T& ..."。您的两个变量
foo1和foo2是非常量左值,您希望用于存储最大值的变量Foo& foo也是如此。那你为什么要在任何地方介绍const?只需从您的max中删除const- 尽管也许您可以将其重命名为max_lvalue_ref以明确它的作用。 -
@AaronMcDaid 我想通过 const 通知编译器/程序员它们不会改变(想象一下,如果我们正在处理更复杂的函数)。
-
@AgrimPathak。 “他们不会改变”。你的意思是
max不会尝试更改它们?
标签: c++ reference return max constants