6

我通常更喜欢尽可能使用引用而不是指针,我认为它使语法更清晰。在这种情况下,我有一个类:

class Foo
{
public:
    Foo(Bar & bar) : bar_(bar) {}

private:
    Bar & bar_;
};

operator=()被编译器隐含地删除了这样一个类,因为一旦设置了引用,它就不能改变(我可以在技术上定义我自己的不会改变 bar_,但这不是必需的行为,所以我宁愿如果我尝试分配 foo,编译器会抱怨)。

我需要的是一个std::vector<Foo> v;. 这在 C++11 之前是不可能的,因为模板参数必须是 CopyAssignable。事实上,当我打电话时v.push_back(Foo(bar));,编译器会抱怨。但我觉得从 C++11 和 Move 语义开始就有可能。

我的问题是:是否有使用 C++11 的解决方法可以构建这样的向量,或者我是否陷入这种情况并且无法使用指针而不是引用?如果有解决方法,我将非常感谢代码片段,因为我不熟悉移动语义。

4

3 回答 3

6

由于完美的转发, Voilaemplace_back能够完成这项工作。

#include <vector>                                                                  

class Bar{};                                                                       
class Foo                                                                          
{                                                                                  
public:                                                                            
    Foo(Bar & bar) : bar_(bar) {}                                                  

private:                                                                           
    Bar & bar_;                                                                    
};                                                                                 
using namespace std;                                                               
int main() {                                                                       
    vector<Foo> v;                                                                 
    Bar bar;
    v.emplace_back(bar);                                                     
} 

您还可以将引用本身存储在std::reference_wrapper使用 like的容器中std::vector<std::reference_wrapper<int>> v

于 2013-11-06T00:47:28.533 回答
1

使用v.emplace_back(bar)而不是push_back. 它将在为其分配Foo的内存中适当地构造一个vector,因此不需要复制。只需传递emplace_back参数来构造一个Foo.

于 2013-11-06T00:47:42.363 回答
0

容器的模板参数不一定是 CopyAssignable,它取决于您对容器执行的操作,如果您确实使用需要 CopyAssignable 或 MoveAssignable 的操作,则不能随意使用引用(即使具有移动语义)。但如果你只使用其他操作(见标准),那就没问题了。有些操作只需要 CopyInsertable、MoveInstable 和/或 EmplaceConstructible。

于 2013-11-06T00:59:16.217 回答