我正在编写一个使用共享指针构建复杂节点结构的库。由于结构中可能存在循环,并且为了避免内存泄漏,我在构建结构时决定采用以下策略:每当我传递一个临时对象时,我都使用shared_ptr(获取所有权);每当我通过左值时,我都会使用weak_ptr。根据我的分析和库接口的设计方式,这应该完全避免循环。
但是,我在使用函数重载时遇到问题,无法理解参数是rvalue还是左值。这是我得到的错误的一个非常简单的例子:
#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)
^
所以,显然编译器无法区分这两个调用。我认为rvalue函数优先于pass-by-value函数,但显然我错了。
另外:我不能声明该函数采用const引用,因为我只想取得所有权,然后随意修改对象,因此引用不应该是常量。
关于如何解决这个问题的任何想法?
答案 0 :(得分:6)
变化:
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
可以绑定到值或右值引用(两者都是完全匹配)。但随着变化,没有歧义。