'auto'和显式变量声明表现不同

时间:2013-01-25 16:38:39

标签: c++ c++11

我有这样的事情:

class Bar;

class Foo()
{
 public:
   Foo() : bar(new Bar());
   Bar& GetBar() { return *bar.get(); }
 private:
   std::unique_ptr<Bar> bar;
};

void main()
{
   Foo foo;
   auto bar1 = foo.GetBar();
   auto bar2 = foo.GetBar(); //address of bar2 != address of bar1. why?

   Bar& bar3 = foo.GetBar();
   Bar& bar4 = foo.GetBar(); //address of bar3 == address of bar4.
}

似乎'auto'变量是副本,因为我没有使用相同的内存地址返回Bars。 如果我明确地将变量定义为Bar引用(Bar&amp;),那么一切都按照我的预期运行。

我应该提到我正在编译vs2012。这是怎么回事?

感谢。

3 个答案:

答案 0 :(得分:22)

auto bar1 = …总是声明副本。 auto &&bar1选择最接近的可能引用类型,这就是您想要的。

auto &&完美转发习语。

如果您想要特定的话,还可以使用auto的其他复合类型,例如auto const &auto *

答案 1 :(得分:13)

auto的作用类似于模板参数推导。 bar1bar2类型为Bar,因此它们是独立副本; bar3bar4的类型为Bar &,并且是对同一*foo.bar的引用。

答案 2 :(得分:1)

<强>代码:

X& getter() {
    static X value;
    return value;
}

print("X:");
X x0 = getter();
auto x0a = getter();
x0.printAddress();
x0a.printAddress();

print("X&:");
X& x1 = getter();
auto& x1a = getter();
x1.printAddress();
x1a.printAddress();

print("const X&:");
const X& x2 = getter();
const auto& x2a = getter();
x2.printAddress();
x2a.printAddress();

print("X&&:");
print("Rvalue can't be bound to lvalue");
X&& x3 = getter();
auto&& x3a = getter();
x3.printAddress();
x3a.printAddress();

<强>结果:

X:
0037F807
0037F7FB
X&:
00D595BA
00D595BA
const X&:
00D595BA
00D595BA
X&&:
Rvalue can't be bound to lvalue
00D595BA

<强>结论:

auto表示:“将我替换为类型,除非我auto&&然后找到最适合的表单”。