编译器生成的move构造函数的行为是什么?

问题描述 投票:33回答:6

std::is_move_constructible<T>::value == true是否暗示T具有可用的move构造函数?如果是这样,它的默认行为是什么?

考虑以下情况:

struct foo {
    int* ptr;
};

int main() {
    {       
        std::cout << std::is_move_constructible<foo>::value << '\n';
        foo f;
        f.ptr = (int*)12;
        foo f2(std::move(f));
        std::cout << f.ptr << ' ' << f2.ptr << '\n';
    }
    return 0;
}

并且输出是:

1
0000000C 0000000C

我认为f.ptr应该是nullptr。因此,在这种情况下,

  1. f2移动是否已构造?
  2. 如果是这样,右值是否应该无效?
  3. 我怎么知道一个类的实例是否可以正确地移动构造(使旧的实例无效?)>]
  4. ((我正在使用VS11。)

更新

move构造函数的默认行为与复制构造函数相同,对吗?如果是真的,

  1. 我们一直期望移动ctor窃取从其移走的对象的资源,而默认对象的行为不符合预期,那么拥有默认移动ctor的意义何在?
  2. 我怎么知道一个类是否具有自定义的move构造函数(可以保证其正常运行?)]
  3. foo f2(std::move(f));在我声明一个时似乎调用复制ctor,请参阅:

    struct foo {
        int* ptr;
        foo() {}
        foo(const foo& other) {
            std::cout << "copy constructed\n";
        }
    };
    
    int main() {
        {       
            std::cout << std::is_move_constructible<foo>::value << '\n';
            foo f;
            foo f2(std::move(f));
        }
        system("pause");
        return 0;
    }
    

现在输出是:

1
copy constructed

如果foo具有移动构造函数,那么foo f2(std::move(f))不会调用它吗?

所以现在我的问题是:如何知道一个类是否具有移动ctor,如果有,则如何显式调用它?

我想做的是...
template<typename T, bool has_move_ctor>
struct MoveAux;

template<typename T>
struct MoveAux<T, true> {
    static void doMove(T* dest, T* src) {
        new(dest) T(std::move(*src)); //move ctor
    }
};

template<typename T>
struct MoveAux<T, false> {
    static void doMove(T* dest, T* src) {
        new(dest) T(*src); //copy ctor
        src->~T();
    }
};

template<typename T>
inline doMove(T* dest, T* src) {
    MoveAux<T,/*a trait*/>::doMove(dest, src);
}

所以我认为std::is_move_constructible<T>::value可以传递给模板,而现在我看到此特征仅关心T t(T())是有效的表达式,它可以调用T::T(const T&)。现在假设T是一个自定义类,那么我希望以上模板的行为类似于:

  1. 如果不声明移动ctor,我希望该模板方法调用MoveAux<T,false>::doMove
  2. 如果我声明一个,则需要它调用MoveAux<T,true>::doMove
  3. 是否可以进行这项工作?

std :: is_move_constructible :: value == true表示T具有可用的move构造函数吗?如果是这样,它的默认行为是什么?考虑以下情况:struct foo {int * ...

c++ c++11 move-semantics
6个回答
22
投票

std::is_move_constructible<T>::value == true是否暗示T具有可用的move构造函数?


5
投票
std :: is_move_constructible :: value == true表示T具有可用的move构造函数吗?

没有它指出您可以std::unique_ptr。这是否使用move构造函数或copy构造函数与此特性无关。


3
投票
move构造函数的默认行为与副本相同构造函数,对吗?如果是真的

没有这是不对的。这仅适用于原始类型。它类似于复制构造函数。


2
投票
请注意,Visual Studio 2012 / VC ++ 11确实

支持编译器生成的move构造函数;实际上,请考虑来自pointer博客文章(重点是我)的引言:
Rvalue参考v3.0添加了新规则以自动生成移动构造函数和移动赋值运算符。此

在VC11中不会实现


0
投票
n3376 12.8 / 15

非工会类X的隐式定义的copy /

move构造函数


0
投票
如果foo具有move构造函数,那么foo f2(std :: move(f))不会调用它吗?提供副本构造函数时,没有默认的move构造函数。添加以下行以获取它(并注意更改)。foo(foo && ifm)= default;
© www.soinside.com 2019 - 2024. All rights reserved.