vendredi 17 février 2017

How bad is an idea of specializing function templates from std namespace?

There's a problem I have with proxy objects and move semantics. They don't always combine very well. In my container class I have and overloaded operator[] that employs lazy element creation within the container. So operator[] returns a proxy object that keeps either a reference to an existing element of container or a place for the potential new element. The idea is that whenever proxy object is accessed in a specific manner or when something is assigned to it, a new element is automatically created in the container in that place.

The problem is in the way the proxy object is returned:

Proxy operator [](std::string name);

I am forced to return by value because I want the caller to manage the lifetime of proxy. The problem with returning by value is that the result of operator [] call is a prvalue, meaning that it will always be moved whenever function is called to initialize or assign a new object:

/// Element of container identified by name "foo" is moved from.
Element foo(container["foo"]);
/// Same with bar...
foo = container["bar"];

I want my proxy to be move assignable to an element, to have a smoth user-expirience. But I want it to be in a usual, expected fasion, like this:

Element foo = std::move(container["foo"]);

For all I know, it can be achieved through a second proxy object MovableProxy. According to this strategy, I want to configure Proxy in such a way that it can only be copied. Then I want to specialize std::move for Proxy type so it will return MovableProxy when supplied with a rvalue or lvalue of Proxy:

namespace std
{

MovableProxy move(Proxy & foo)
{
    ...
}

MovableProxy move(Proxy && foo)
{
    ...
}

} // namespace std

So, how bad is an idea of specializing template function std::move for my own class? And what awful pitfalls are waiting around the corner.

Aucun commentaire:

Enregistrer un commentaire