Mover a geração de função de membro

Código:

#include <iostream>
#include <ios>
#include <string>
#include <type_traits>
#include <memory>

struct value
{
    ~value() = default;
    std::unique_ptr<std::string> s;
};

int main()
{
    std::cout << std::boolalpha;
    std::cout << std::is_move_constructible<value>::value << '\n';
    std::cout << std::is_move_assignable<value>::value    << '\n';

    using str_ptr = std::unique_ptr<std::string>;
    std::cout << std::is_move_constructible<str_ptr>::value << '\n';
    std::cout << std::is_move_assignable<str_ptr>::value    << '\n';

    return 0;
}

Saída (compilada com g ++ v4.7.2,http://ideone.com/CkW1tG):

false
false
true
true

Como eu esperava,value não é mover construtível e não é mover atribuível porque:

~value() = default;

é umdeclarado pelo usuário destrutor, que impede a geração implícita de membros de movimento de acordo com a seção12,8 (ver abaixo). Se o destruidor for removido,value é mover construtível e mover atribuível, como eu esperavahttp://ideone.com/VcR2eq).

No entanto, quando a definição devalue é alterado para (http://ideone.com/M8LHEA):

struct value
{
    ~value() = default;
    std::string s;      // std::unique_ptr<> removed
};

a saída é:

true
true
true
true

value é inesperadamente mover construtível e mover atribuível. Estou entendendo mal ou isso é um erro de compilador?

fundo: Eu forneci uma resposta paraisto questão e foi informado de queTree<> era móvel, mas não tenho certeza e estou tentando determinar com certeza se é ou não.

Seção8.4.2 Funções com default explícito da norma c ++ 11 (projecto n3337):

Funções com default explícito e funções declaradas implicitamente são coletivamente chamadas de funções default, e a implementação deve fornecer definições implícitas para elas (12.1 12.4, 12.8), o que pode significar defini-las como excluídas. Uma função de membro especial é fornecida pelo usuário se for declarada pelo usuário e não for explicitamente padronizada ou excluída em sua primeira declaração. Uma função padrão explicitamente fornecida pelo usuário (ou seja, explicitamente padronizada após sua primeira declaração) é definida no ponto em que é explicitamente padronizada; se tal função é implicitamente definida como excluída, o programa é mal formado. [Nota: Declarar uma função como padrão após sua primeira declaração pode fornecer execução eficiente e definição concisa ao mesmo tempo em que ativa uma interface binária estável para uma base de código em evolução. — End note]

Seção12.8 Copiando e movendo objetos de classe (ponto 9):

If the definition of a class X does not explicitly declare a move constructor,
one will be implicitly declared as defaulted if and only if
- X does not have a user-declared copy constructor,
- X does not have a user-declared copy assignment operator,
- X does not have a user-declared move assignment operator,
- X does not have a user-declared destructor, and
- the move constructor would not be implicitly defined as deleted.

questionAnswers(1)

yourAnswerToTheQuestion