我希望找到最大的
Foo
,并在其上调用一个非常量方法inc()
。当然,在查找最大值时,我不想创建任何副本或移动对象,即我不想使用Foo foo = std::max(foo1, foo2)
。我尝试编写自己的max函数,但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;
}
Foo copy() const& { return *this; }
,这样你就可以写成std::max(fooA,fooB).copy().inc();
。有时候没有名称的复制构造函数会让人感到痛苦。 - MSaltersfoo1
和foo2
都是非const lvalue,而你想要用来存储最大值的变量Foo&foo
也是非const lvalue。所以为什么要在任何地方引入const
呢?从你的max
中省略const
即可——虽然也许你可以将其重命名为max_lvalue_ref
以明确其功能。 - Aaron McDaidmax
不会试图改变它们? - Aaron McDaidmax
以const方式获取它们,那么编译器可能会假设foo1
和foo2
在程序中任何地方都不能被修改。它们唯一被引用的时候是通过非const引用,因此这似乎是一个合理的假设。编译器可能会进行不正确的优化,基本上假设foo1
和foo2
在程序中没有被修改。因此,如果你在最后打印foo1
和foo2
的值,编译器可能会打印旧的(未递增)值。也许我有点夸张,但我怀疑这种不正确的假设是由优化所允许的。 - Aaron McDaid