2012-05-28 9 views
22

He estado tratando de definir un constructor de movimiento predeterminado en una clase con una variable de miembro boost::optional.¿Es posible mover un impulso :: opcional?

#include <boost/optional.hpp> 
#include <utility> 
#include <vector> 

struct bar {std::vector<int> vec;}; 

struct foo { 
    foo() = default; 
    foo(foo&&) = default; 
    boost::optional<bar> hello; 
}; 

int main() { 
    foo a; 
    foo b(std::move(a)); 
} 

Mi compilador soporta tanto mover la semántica y constructores se mueven en mora, pero no puedo conseguir que esto funcione.

% clang++ foo.cc -std=c++11 -stdlib=libc++ 
foo.cc:15:7: error: call to deleted constructor of 'foo' 
    foo b(std::move(a)); 
    ^~~~~~~~~~~~~ 
foo.cc:9:3: note: function has been explicitly marked deleted here 
    foo(foo&&) = default; 
^
1 error generated. 

¿Hay una manera de mover un boost::optional sin modificar el código fuente de Boost? ¿O debería esperar hasta que Boost apoye el movimiento?

Tuve el mismo problema con boost::any en el pasado.

+3

Alguien en #boost me señaló esto: https://svn.boost.org/trac/boost/ticket/1841 –

Respuesta

17

En cuanto al código fuente boost::optional, no define los constructores de movimiento ni las asignaciones de movimiento. Sin embargo, sí define el constructor y la asignación de copia, que impiden que el compilador genere de forma automática el constructor de movimientos y la asignación para él.

Ver Move constructor — Q&A:

el compilador generará de forma implícita movimiento constructor como movimientos miembros en cuanto, a menos que haya definido explícitamente un constructor de copia o copia/asignación de movimiento o un destructor

Como Luc Danton sugiere que debe haber una cura para eso. Vamos a tratar utilizando swap para mover boost::optional con la esperanza de que la creación de un vacío boost::optional es barato y luego sólo cambio el default-construida boost::optional con la del valor r foo, por ejemplo:

foo(foo&& b) { 
    hello.swap(b.hello); 
} 

y lo mismo para el mover la asignación

+0

¡Ese es un diagnóstico correcto, pero necesita una cura para completar esta respuesta! –

+0

¡Me hiciste pensar en Luc!) –

+0

Hmm, eso es desafortunado. Podría escribir una clase contenedora que permita mover usando 'std :: swap', y conversión implícita a' boost :: optional'. Espero que esto se solucione en la/a próxima versión de Boost. –

3

No está claro qué tan alto en la agenda C++ 11 soporte de características para boost :: optional is.

Encontré un buen compañero en Internet que me dio algunos de sus propios códigos bajo una licencia de impulso ... que todavía está experimentando algunos ajustes. Está en un punto donde funciona para mí. Tal vez pueda ayudar cualquiera que busque en esta pregunta:

https://github.com/hostilefork/CopyMoveConstrainedOptional

También hay un esfuerzo de grupo más grande para definir un std::optional que ha estado ocurriendo ... pero su implementación de referencia no era capaz de manejar algunos de los casos que tenían:

http://kojot.sggw.waw.pl/~akrzemi1/optional/tr2.optional.proposal.html

Cuestiones relacionadas