gpt4 book ai didi

c++ - 当不应调用该构造函数时,复制参数会调用已删除的构造函数

转载 作者:搜寻专家 更新时间:2023-10-31 00:54:09 24 4
gpt4 key购买 nike

#include <memory>

template <typename T>
class Wrapper {
public:
Wrapper() = delete;
Wrapper(const Wrapper&) = delete;
Wrapper(Wrapper&&) = delete;

~Wrapper() = default;

Wrapper(const T&) = delete;
Wrapper(T&& in) : instance{std::move(in)} {}

T instance;
};

void foo(Wrapper<std::shared_ptr<int>>) {}

int main() {
auto ptr = std::make_shared<int>(1);
foo(std::move(ptr));
}

这在 C++17 中一直有效,所以我从未想过,但为什么这段代码会尝试在 C++14 中调用 move 构造函数?它不应该在函数参数中就地构建吗?这似乎不是 c++17 的问题,但不是用 c++14 编译的。

我看到的唯一解决方法是使 foo 参数成为右值,但是我可以做些什么来使它工作而不使 foo 中的参数成为右值在 C++14 中?


我的第一个想法是,临时对象必须是构造函数才能传递给函数,但更令人惊讶的是,即使使用 -fno-elide-constructors 并取消删除似乎没有调用的 move 构造函数和复制构造函数!这是 gcc 和 clang 中的错误吗?

参见 https://wandbox.org/permlink/f6sa5Rm3NxZLy5P1对于错误看看奇怪的行为 https://wandbox.org/permlink/Kh6CG4OVbUAjvEZz

最佳答案

当您调用 foo(std::move(ptr)); 时你没有给它 Wrapper<std::shared_ptr<int>> .因此,编译器生成一个临时文件并使用它来构造 foo的参数。现在,这个可以去掉了,我们可以直接构造一个Wrapper<std::shared_ptr<int>>但是 move/复制构造函数仍然需要可访问,即使它从未被调用。

在 C++17 中,这不再发生。我们有guaranteed copy elision这意味着没有临时物化,而是直接构造参数。

关于c++ - 当不应调用该构造函数时,复制参数会调用已删除的构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46226516/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com