【问题标题】:'auto' and explicit variable declaration behaving differently'auto' 和显式变量声明的行为不同
【发布时间】:2013-01-25 16:38:39
【问题描述】:

我有这样的事情:

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.
}

似乎“自动”变量是副本,因为我没有使用相同的内存地址返回 Bars。 如果我将变量明确定义为 Bar 引用 (Bar&),那么一切都会按我的预期工作。

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

谢谢。

【问题讨论】:

标签: c++ c++11


【解决方案1】:

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

auto &amp;&amp;完美转发的成语。

您还可以将其他复合类型与auto 一起使用,例如auto const &amp;auto *,如果您想具体一点的话。

【讨论】:

  • +1,我不知道 auto 引用折叠以及模板类型参数。
  • @SethCarnegie 是的,我所有变量中的很大一部分都被声明为auto &amp;&amp;……这几乎是我的默认值:)
【解决方案2】:

auto 类似于模板参数推导。 bar1bar2Bar 类型,所以它们是独立的副本; bar3bar4 具有类型 Bar &amp; 并且是对相同 *foo.bar 的引用。

【讨论】:

  • 但是 GetBar() 返回一个 Bar& ,我想 auto 会将变量设置为函数的返回类型。无论如何,我在这里找到了解释:cprogramming.com/c++11/… 在标题为:自动、引用、指针和常量的部分中。有点奇怪,那个。
  • @Aeluned:你可以想象任何你想要的,但事实是auto 就像模板参数推导一样工作。当你有template &lt;typename T&gt; void f(T); 并调用f(foo.getBar()); 时,你会推断出T = Bar...
  • @Aeluned:在很多情况下您不希望这样做,例如,当访问对象中的字段时,如果访问器返回一个常量引用,您希望 now i>,而不是对潜在变化值的引用。当前规范允许您通过添加&amp; 来选择是否需要引用,如auto&amp; bar3 =...
【解决方案3】:

代码:

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&amp;&amp;,然后找到最合适的形式”。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-04-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多