代码之家  ›  专栏  ›  技术社区  ›  knulp

右值和左值的重载函数

  •  3
  • knulp  · 技术社区  · 10 年前

    我正在编写一个使用共享指针构建复杂节点结构的库。由于结构中可能存在循环,并且为了避免内存泄漏,我决定在构建结构时采用以下策略:每当传递给我一个临时对象时,我使用shared_ptr(获取所有权);每当我被传递左值时,我都会使用weak_ptr。根据我的分析和库接口的设计方式,这应该完全避免循环。

    然而,我在使用函数重载来理解参数是右值还是左值时遇到了问题。下面是一个非常简单的错误示例:

    #include <iostream>
    #include <memory>
    
    using namespace std;
    
    class MyClass {
    public:
        int a;
        // this class contains some pointers to the node structure
    };
    
    MyClass fun(MyClass &&x, MyClass &&y)
    {
        // should produce an object that has ownership of the two others
    }
    
    MyClass fun(MyClass x, MyClass y)
    {
        // should not take ownership, but just copy the pointer
    }
    
    int main()
    {
        MyClass x, y;
    
        fun(x, y);
        fun(MyClass(), MyClass());
    }
    

    使用g++4.8.2编译时,我得到以下错误:

    example.cpp: In function ‘int main()’:
    example.cpp:29:29: error: call of overloaded ‘fun(MyClass, MyClass)’ is ambiguous
         fun(MyClass(), MyClass());
                                 ^
    example.cpp:29:29: note: candidates are:
    example.cpp:12:9: note: MyClass fun(MyClass&&, MyClass&&)
     MyClass fun(MyClass &&x, MyClass &&y)
             ^
    example.cpp:18:9: note: MyClass fun(MyClass, MyClass)
     MyClass fun(MyClass x, MyClass y)
             ^
    

    因此,编译器显然无法区分这两个调用。我认为右值函数优先于传递值函数,但显然我错了。

    另外:我不能声明函数获取常量引用,因为我只想获取所有权,然后在以后随意修改对象,所以引用不应该是常量。

    对我如何解决这个问题有什么想法吗?

    1 回复  |  直到 10 年前
        1
  •  9
  •   Barry    10 年前

    更改:

    MyClass fun(MyClass x, MyClass y)
    MyClass fun(MyClass&& x, MyClass&& y)
    

    收件人:

    MyClass fun(MyClass& x, MyClass& y)      // for lvalues
    MyClass fun(MyClass&& x, MyClass&& y)    // for rvalues
    

    在最初的示例中 MyClass 可以绑定到值或右值引用(两者完全匹配)。但随着变化,没有任何歧义。