C++ 标准::向量<;Foo>;当Foo的某些成员是引用时

C++ 标准::向量<;Foo>;当Foo的某些成员是引用时,c++,c++11,stdvector,move-semantics,C++,C++11,Stdvector,Move Semantics,只要可能,我通常更喜欢使用引用而不是指针,在我看来,这使语法更清晰。在本例中,我有一个类: class Foo { public: Foo(Bar & bar) : bar_(bar) {} private: Bar & bar_; }; operator=()被编译器隐式删除,因为一旦设置了引用,它就无法更改(从技术上讲,我可以定义我自己的引用,但它不会更改bar,但这不是必需的行为,所以如果我试图分配一个foo,我宁愿编译器抱怨) 我需要的是一个std::

只要可能,我通常更喜欢使用引用而不是指针,在我看来,这使语法更清晰。在本例中,我有一个类:

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

private:
    Bar & bar_;
};
operator=()
被编译器隐式删除,因为一旦设置了引用,它就无法更改(从技术上讲,我可以定义我自己的引用,但它不会更改bar,但这不是必需的行为,所以如果我试图分配一个foo,我宁愿编译器抱怨)

我需要的是一个
std::vector v。这在C++11之前是不可能的,因为模板参数必须是可复制的。事实上,当我调用
v.push_back(Foo(bar))。但我觉得这是可能的,因为C++11和Move语义

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

瞧,由于完美的转发,我能够完成这项工作

#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);                                                     
} 
#包括
类条{};
福班
{                                                                                  
公众:
Foo(Bar&Bar):Bar_(Bar){}
私人:
酒吧&酒吧;
};                                                                                 
使用名称空间std;
int main(){
向量v;
酒吧;
v、 后置炮台(横杆);
} 

您还可以将引用自身存储在容器中,使用类似于
std::vector v

的Use而不是
push_back
。它将在分配给它的内存中构建一个
Foo
,因此不需要复制。只需将参数传递回
emplace\u
即可构建
Foo

容器的模板参数不必是可复制分配的,它取决于您对容器执行的操作,如果您确实使用了需要可复制分配或可移动分配的操作,则不能按照您的意愿使用引用(即使使用移动语义)。但是如果您只使用其他操作(请参见标准),也可以。一些操作只需要CopyInsertable、movestatable和/或EmplaceConstructible。

我认为emplaceback就是您要寻找的可能重复的Does
Foo(const-Foo&&Foo):bar_(Foo.bar_){
不能解决这个问题吗?我确信,根据类定义其构造函数的方式,
push_-back
使用隐式移动生成可以很好地工作。您的示例对我来说编译得很好?您需要或
boost::optional
。它们都有指针大小。
boost::optional
/
boost::optional
具有所需的语义。@Boris您能否发布一个未编译的完整示例,因为我实际实现了示例的push_-back编译too@Boris抱歉,我会看一看,但可能很难找出问题所在,因为我没有编译器。您应该将Foo构造函数的参数直接传递给
emplace\u back
,否则您将创建一个不必要的临时对象并调用复制/移动构造函数。@Trillian如果您说的是第一个emplace\u back,那么我将删除它it@aaronman那应该是
v.emplace\u back(bar)
而不是
v.emplace\u back(Foo(bar))
emplace
旨在为正在创建的类型获取构造函数参数,而不是在该类型的对象上。@Boris-是的,gcc 4.6远远落后于c++11支持。4.8更好。+1为了提供正确的语法,我接受了aaronman作为代码片段:)