11

この静的アサーションが起動することを期待していました。

#include <type_traits>
#include <memory>

int main() {
  static_assert(std::is_copy_constructible<std::unique_ptr<int>>::value, "UPtr has copy constructor?");
}

しかし、そうではありません。

MSVC12 を使用してコンパイル:

Microsoft (R) C/C++ 最適化コンパイラ バージョン 18.00.31101 for x64

4

2 に答える 2

0

クラスをコピー不可にする 4 つの方法を次に示します。

#include <stdio.h>
#include <type_traits>

class A {
public:
    A(const A&) = delete;
    void operator=(const A&) = delete;
};

class B {
private:
    B(const B&) = delete;
    void operator=(const B&) = delete;
};

class C {
public:
    C(const C&) = delete;
    void operator=(const C&) = delete;
    void operator=(C) = delete;
};

class D {
private:
    D(const D&) = delete;
    void operator=(const D&) = delete;
    void operator=(D) = delete;
};

int main() {
    printf("%d %d\n", std::is_copy_constructible<A>::value, std::is_copy_assignable<A>::value);
    printf("%d %d\n", std::is_copy_constructible<B>::value, std::is_copy_assignable<B>::value);
    printf("%d %d\n", std::is_copy_constructible<C>::value, std::is_copy_assignable<C>::value);
    printf("%d %d\n", std::is_copy_constructible<D>::value, std::is_copy_assignable<D>::value);
}

MSVC2013 x64 ( 18.00.40629 for x64) では、次のように表示されます。

1 1    //A
0 1    //B
1 0    //C
0 0    //D

適切なコンパイラでは、8 つの値はすべてゼロでなければなりません。

残念ながら、これは、独自のクラスであっても、MSVC2013 のバグを回避する良い方法ではありません。引数を値で受け取る代入演算子を宣言すると、同じクラスでムーブ代入を宣言できないためです (あいまいなオーバーロードにより、ムーブ代入はコンパイルされません)。

PS割り当てを修正するための重要なアイデアは、この関連する回答から取られました。

于 2018-03-04T07:25:24.777 に答える