【问题标题】:Assignment to a constructor? (like a tuple-tier)分配给构造函数? (就像一个元组层)
【发布时间】:2013-02-05 15:58:32
【问题描述】:

当我可以分配给“看起来”像构造函数的函数时,为什么我不能分配给构造函数?

例子:

struct Bar {
   Bar() : b_(false) {}
   Bar(bool b) : b_(b) {}
};

struct Foo {
   Foo(Bar const & bar) : bar_(bar) {}
   Foo operator=(Foo const & f) { return Foo(f.bar_); }
   const Bar & bar_;
}

Foo bool_to_foo(bool b) { return Foo(Bar(b)); }

Foo MakeFoo(Bar const & bar) { return Foo(bar); }

为什么会这样:

Bar bar;
MakeFoo(bar) = bool_to_foo(true);

什么时候这不起作用?

Bar bar;
Foo(bar) = bool_to_foo(true);  // Error: 'bar': redefinition; different basic types

MakeFoo(.) 和 Foo(.) 具有相同的签名和相同的功能。

构造函数有什么特别之处?

【问题讨论】:

  • 你永远不能“分配给一个函数”。不过,您可以分配给函数对象!
  • 哦,当您在代码中的表达式中看到Foo() 时,它从不“构造函数”。不可能直接调用或引用构造函数。
  • 您没有在代码中“分配给函数”,而是尝试分配给函数的返回值。
  • @LightnessRacesInOrbit--看看 boost::tuples::tie,他们非常有效地使用“分配给函数”。

标签: c++ constructor assignment-operator


【解决方案1】:

这一行:

Foo(bar) = bool_to_foo(true);

不做你认为它做的事。它确实声明了一个用bar 初始化的临时对象。 它实际上做的是声明一个名为bar 类型为Foo 的对象,并用值bool_to_foo(true) 对其进行初始化。

从这个意义上说,它完全等价于:

Foo bar = bool_to_foo(true);

由于您在范围内已经有一个名为 bar 的对象,因此这是一个重新定义。


如果你仍然想做你想做的事情,你可以尝试:
Foo((0,bar)) = bool_to_foo(true);

但是,由于这既丑陋又令人困惑,我不会进一步描述它。

【讨论】:

  • @LightnessRacesinOrbit s/d/D/g :P
  • @Robᵩ--非常有见地。绝对是语法上的怪异(或至少是出乎意料的)。
  • @R.MartinhoFernandes: true
【解决方案2】:

MakeFoo() 函数返回一个对象,然后可以将其分配给该对象(尽管我怀疑它带有编译器警告会抱怨分配给临时对象)。但是,正如您所推测的,C++ 标准对构造函数给予特殊处理。虽然我不完全确定,但我怀疑 = bool_to_foo(true) 部分被视为初始化,而不是分配。这会导致错误,因为 foo 没有复制构造函数。

Rob 的 Foo(bar) 交易也一针见血。 C++ 语法有时会很奇怪。

在任何情况下,这两种形式中的任何一种都是不好的做法 - 分配给右值可能不是您想要的,如果是的话,很可能会让人们感到困惑。

【讨论】:

  • @Robert--C++ 中的“坏习惯”似乎是 Haskell 中的 SOP ......他们似乎一直在分配类型构造函数。只是想稍微扩展到 FP 世界!
  • @DavidH:Haskell 很棒。但是风格/实践不会跨语言移植。在 C++ 中,这种语法的含义与在 Haskell 中的用法完全不同。 MakeFoo(bar) = baz(quuz) 在 c++ 中的意思是该表达式的目的 副作用。与 Haskell 中的任何东西完全对立。
猜你喜欢
  • 2020-02-03
  • 2022-01-18
  • 2018-02-09
  • 1970-01-01
  • 2020-08-25
  • 1970-01-01
  • 1970-01-01
  • 2020-12-23
  • 2021-11-24
相关资源
最近更新 更多