2012-04-13 6 views
0

可能性の重複:
Preventing non-const lvalues from resolving to rvalue reference instead of const lvalue reference
Conflict between copy constructor and forwarding constructor移動コンストラクタと移動代入演算子が呼び出され、コピーされないのはなぜですか?

I私がのstd :: unique_ptrをを格納するために必要なこれらのクラス(適応ブースト::任意の)持っている:

class any 
{ 
public: 
    any() 
    : content(0) 
    { 
    } 

    any(any const&) = delete; 

    any(any && other) 
    : content(other.content) 
    { 
    content = 0; 
    } 

    template<typename ValueType> 
    any(ValueType const& value) 
    : content(new holder<ValueType>(value)) 
    { 
    } 

    template<typename ValueType> 
    any(ValueType && value, 
    typename std::enable_if<!std::is_lvalue_reference<ValueType>::value, 
    void>::type* = 0) 
    : content(new holder<ValueType>(std::move(value))) 
    { 
    } 

    ~any() 
    { 
    delete content; 
    } 

public: // modifiers 

    any & swap(any & rhs) 
    { 
    std::swap(content, rhs.content); 
    return *this; 
    } 

    any & operator=(const any &) = delete; 

    any & operator=(any && rhs) 
    { 
    return swap(rhs); 
    } 

    template<typename ValueType> 
    any & operator=(ValueType const& rhs) 
    { 
    any(rhs).swap(*this); 
    return *this; 
    } 

    template<typename ValueType> 
    typename std::enable_if<!std::is_lvalue_reference<ValueType>::value, 
    any&>::type operator=(ValueType && rhs) 
    { 
    any(std::move(rhs)).swap(*this); 
    return *this; 
    } 

public: // queries 

    bool empty() const 
    { 
    return !content; 
    } 

    const std::type_info & type() const 
    { 
    return content ? content->type() : typeid(void); 
    } 

private: // types 

    class placeholder 
    { 
    public: // structors 

    virtual ~placeholder() 
    { 
    } 

    public: // queries 
    virtual const std::type_info & type() const = 0; 
    }; 

    template<typename ValueType> 
    class holder : public placeholder 
    { 
    public: // structors 
    template <class T> 
    holder(T && value) 
     : held(std::forward<T>(value)) 
    { 
    } 

    holder & operator=(const holder &) = delete; 

    public: // queries 
    virtual const std::type_info & type() const 
    { 
     return typeid(ValueType); 
    } 

    public: 

    ValueType held; 
    }; 

private: // representation 

    template<typename ValueType> 
    friend ValueType * any_cast(any *); 

    template<typename ValueType> 
    friend ValueType * unsafe_any_cast(any *); 

    placeholder * content; 
}; 

とこのテストケース:

any a; 
any b(a); 

b = a; 

と、この1:私の恐怖に

std::map<int, int> map({{1,1},{2,2}}); 
any b(map); 
std::cout << map.size() << std::endl; // displays 0 

、GDBの下で、私は(も、マップから)bを構築し、割り当てる際移動コンストラクタと移動代入演算子が呼び出されることに気付きました、 astd::moveというタグは付けていませんが、それは一時的ではありません。なぜ誰かが説明できますか?

+1

一貫したインデントが本当に役に立ちます。 –

+0

私は後継のためのboost :: any hackを編集しました。 – user1095108

答えて

0

私の最初の答えは間違っていました。あなたの非常に読めないコードをもう一度読んだ後、あなたは明示的に移動とデフォルトのコンストラクタを提供していますが、コピーコンストラクタはありません。クラスにのユーザー定義コンストラクタ(いずれも2つあります)のがある場合、コンパイラはそのクラスの他のコンストラクタを生成しません。したがって、クラスにコピーコンストラクタがありません。

を編集してください。私の元の回答に戻ってください(あなたのコメントによって促されます)。 §12.8/ 7 [class.copy]言う:

メンバ関数テンプレートは、そのクラスタイプのオブジェクトにクラスオブジェクトのコピー を実行するためにインスタンス化されることはありません。 [例:

struct S { 
    template<typename T> S(T); 
    template<typename T> S(T&&); 
    S(); 
}; 

S f(); 
const S g; 

void h() { 
    S a(f());   // does not instantiate member template; 
         // uses the implicitly generated move 
    constructor S a(g); // does not instantiate the member template; 
         // uses the implicitly generated copy constructor 
} 

末端例]

コピーのコンストラクタは、メンバテンプレートですが、あなたの移動のコンストラクタがない、後はあなたの場合を例と異なっている(ここで選択されているのでその観点において)。

+0

私の編集で説明したように、このコンストラクタは選択されていません。 –

+0

移動テンプレートコンストラクタが呼び出され、移動コンストラクタではなく、マップから構造をチェックします。移動された理由は何ですか? – user1095108

+0

ええと、私は分かりません。おそらく、問題をローカルで再現できるように最小限のプログラムを提供することができますか? –

関連する問題