Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/neo4j/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 按值将向量返回到引用中_C++ - Fatal编程技术网

C++ 按值将向量返回到引用中

C++ 按值将向量返回到引用中,c++,C++,我有以下代码: std::vector<Info*> filter(int direction) { std::vector<Info*> new_buffer; for(std::vector<Info*>::iterator it=m_Buffer.begin();it<m_Buffer.end();it++) { if(((*it)->direction == direction) {

我有以下代码:

std::vector<Info*> filter(int direction)
{
    std::vector<Info*> new_buffer;
    for(std::vector<Info*>::iterator it=m_Buffer.begin();it<m_Buffer.end();it++)
    {
        if(((*it)->direction == direction)
        {
            new_buffer.push_back(*it);
        }
    }

    return new_buffer;
}

std::vector<Info*> &filteredInfo= filter(m_Direction);
std::向量过滤器(int方向)
{
std::向量新_缓冲区;
对于(std::vector::iterator it=m_Buffer.begin();itdirection==direction)
{
新建缓冲区。将缓冲区向后推(*it);
}
}
返回新的缓冲区;
}
std::vector&filteredInfo=过滤器(m_方向);
有人能解释一下这里发生了什么吗?filter方法是否会按值返回创建一个临时值,而filteredInfo不会因为是引用而被销毁


不知道我是否理解正确。在这种情况下,filteredInfo作为引用和不作为引用之间有什么区别?

编译器应该抱怨这段代码

本声明:

std::vector<Info*> &filteredInfo= filter(m_Direction);
您正在尝试创建对临时对象的引用。即使你的编译器成功了,它也是非法的

你应使用:

std::vector<Info*> filteredInfo= filter(m_Direction);
std::vector filteredInfo=过滤器(m_方向);
它的效率是你想要的。一个
move
操作(C++11)将在那里发生,或者将启动。对于
过滤器的实现
,它应该是基于优化构建的RVO(但这取决于编译器的质量)

但是,您应该注意,您正在将原始指针复制到向量中,我希望您有一个正确的所有权模型?如果没有,我建议您使用智能指针。

以下是发生的情况:

  • std::vector新建\u缓冲区在本地创建对象
  • 返回新的\u缓冲区filter(m\u方向)
    时,code>将
    new\u buffer
    移动到临时对象
  • 现在如果调用
    std::vector filteredInfo=filter(m_方向)
    临时对象将被移动到
    filteredInfo
    ,因此没有不必要的副本,这是最有效的方法
  • 但是,如果调用
    std::vector&filteredInfo=filter(m_方向)
    然后将
    filteredInfo
    绑定到一个临时对象,这是一个糟糕的想法,大多数编译器都会对此抱怨

  • 在这里,你正确地感到困惑,因为有两个独立的奇怪事实混合在一起:

    • 编译器允许将非常量引用绑定到临时引用。从历史上看,这在Microsoft编译器中是一个错误,标准不允许这样做。该代码不应编译
    • 然而,奇怪的是,该标准实际上允许绑定
      const
      对临时对象的引用,并为此制定了一条特殊规则:临时对象不会立即被销毁(就像通常发生的那样),但其寿命将延长到引用的寿命
    代码:

    std::vector<int> foo() {
        std::vector<int> x{1,2,3};
        return x;
    }
    
    int main() {
        const std::vector<int>& x = foo(); // legal
        for (auto& item : x) {
            std::cout << x << std::endl;
        }
    }
    
    不能打电话给我

    foo("Hey, you");
    
    没有特殊规则,因为
    常量char*
    (literal)被隐式转换为临时
    std::string
    ,并作为绑定到常量引用的参数传递


    (1) 从哲学的角度来看,这种模式确实很糟糕,因为一个值就是一个值,一个引用就是一个引用:这两个概念在逻辑上是不同的。然而,C++是性能困扰,尤其是在移动语义之前,传递const引用被认为是传递值的“智能”方式,尽管是一个问题,因为生命周期和混淆问题,并且使优化器变得更困难。在现代编译器中,传递引用应该只用于“大”对象,特别是那些不是要传递的动态构造的对象,或者当您真正感兴趣的是对象标识而不仅仅是对象值时。

    这个编译吗?如果有,您使用的是MSV吗?是的,它的Visual Studio 2005还可以。请注意,这是非标准代码。MSVS允许这样做,但这在大多数其他编译器上不起作用。请提供一个。这会导致内存泄漏吗?当使用对临时?Kobe的引用时,这不是内存泄漏,但如果使用该引用,则肯定是UB。MSVC(Visual Studio)在这里做了一些很好的定义,但它确实依赖于编译器,而不是标准Com共振
    void foo(const std::string& x) { ... }
    
    foo("Hey, you");