O que constitui um estado válido para um objeto “movido de” no C ++ 11?

Eu tenho tentado entender como a semântica de movimento em C ++ 11 deve funcionar, e estou tendo problemas para entender quais condições um objeto movido-a-objeto precisa satisfazer. Olhando para oresponda aqui realmente não resolve a minha questão, porque não consigo ver como aplicá-la aos objetos pimpl de uma maneira sensata, apesar dos argumentos quesemântica de movimento são perfeitos para pimpls.

A ilustração mais fácil do meu problema envolve o idioma pimpl, assim:

class Foo {
    std::unique_ptr<FooImpl> impl_;
public:
    // Inlining FooImpl's constructors for brevity's sake; otherwise it 
    // defeats the point.
    Foo() : impl_(new FooImpl()) {}

    Foo(const Foo & rhs) : impl_(new FooImpl(*rhs.impl_)) {}

    Foo(Foo && rhs) : impl_(std::move(rhs.impl_)) {}

    Foo & operator=(Foo rhs) 
    {
        std::swap(impl_, rhs.impl_);

        return *this;
    }

    void do_stuff () 
    {
        impl_->do_stuff;
    }
};

Agora, o que posso fazer depois de mudar de umFoo? Eu posso destruir o objeto movido de forma segura, e posso atribuir a ele, ambos os quais são absolutamente cruciais. No entanto, se eu tentardo_stuff com minhaFoo, vai explodir. Antes eu adicionei a semântica de movimento para minha definição deFoo, cadaFoo satisfeito o invariável que poderiado_stuffe isso não é mais o caso. Não parece haver muitas alternativas excelentes, já que (por exemplo) colocar o movido deFoo envolveria uma nova alocação dinâmica, que parcialmente anula o propósito de mover a semântica. Eu poderia verificar seimpl_ emdo_stuff e inicializá-lo para um padrãoFooImpl se for, mas isso adiciona um cheque (geralmente espúrio), e se eu tiver muitos métodos significaria lembrar de fazer o check-in em cada um.

Devo desistir da ideia de que ser capaz dedo_stuff é uma invariante razoável?

questionAnswers(2)

yourAnswerToTheQuestion