vendredi 30 janvier 2015

Overload function for rvalues and lvalues

I am writing a library that uses shared pointers to build a complex structure of nodes. Since there can be cycles in the structure, and to avoid memory leakes, I decided to adopt the following strategy when building the structure: whenever I am passed a temporary object, I use a shared_ptr (to get the ownership); whenever I am passed a lvalue, I use a weak_ptr. According to my analysis and the way the library interface is designed, this should avoid cycles altogether.


However, I am having problems in using function overloading to understand when the parameter is a rvalue or a lvalue. Here is a very simplified example of the error I get:



#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());
}


When compiling with g++ 4.8.2 I get the following error:



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)
^


So, apparently the compiler cannot distinguish between the two calls. I thought the rvalue function has precedence over the pass-by-value function, but evidently I was wrong.


Also: I cannot declare the function to take const references, because I want just to take ownership and then later modify the object at will, so the reference should not be constant.


Any ideas on how I may solve this problem?


Aucun commentaire:

Enregistrer un commentaire