Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 复制参数调用已删除的构造函数时,该构造函数不应';别叫了 #包括 样板 类包装器{ 公众: 包装器()=删除; 包装器(常量包装器&)=删除; 包装器(包装器&)=删除; ~Wrapper()=默认值; 包装器(常数T&)=删除; 包装器(T&&in):实例{std::move(in)}{ T例; }; void foo(包装器){} int main(){ 自动ptr=std::使_共享(1); foo(std::move(ptr)); }_C++_C++14_Move_C++17_Deleted Functions - Fatal编程技术网

C++ 复制参数调用已删除的构造函数时,该构造函数不应';别叫了 #包括 样板 类包装器{ 公众: 包装器()=删除; 包装器(常量包装器&)=删除; 包装器(包装器&)=删除; ~Wrapper()=默认值; 包装器(常数T&)=删除; 包装器(T&&in):实例{std::move(in)}{ T例; }; void foo(包装器){} int main(){ 自动ptr=std::使_共享(1); foo(std::move(ptr)); }

C++ 复制参数调用已删除的构造函数时,该构造函数不应';别叫了 #包括 样板 类包装器{ 公众: 包装器()=删除; 包装器(常量包装器&)=删除; 包装器(包装器&)=删除; ~Wrapper()=默认值; 包装器(常数T&)=删除; 包装器(T&&in):实例{std::move(in)}{ T例; }; void foo(包装器){} int main(){ 自动ptr=std::使_共享(1); foo(std::move(ptr)); },c++,c++14,move,c++17,deleted-functions,C++,C++14,Move,C++17,Deleted Functions,这在C++17中一直有效,所以我从未考虑过,但为什么这段代码会尝试在C++14中调用move构造函数呢?它不应该在函数参数中就地构造吗?这似乎不是c++17的问题,但不是用c++14编译的 我看到的唯一解决方法是将foo参数设置为右值,但是我能做些什么来实现这一点,而不将foo中的参数设置为C++14中的右值 我的第一个想法是,为了传递给函数,临时构造函数必须是构造函数,但更令人惊讶的是,即使使用-fno elide构造函数,并取消删除移动构造函数和复制构造函数,似乎也不会调用它们!这是gcc

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

我看到的唯一解决方法是将
foo
参数设置为右值,但是我能做些什么来实现这一点,而不将
foo
中的参数设置为C++14中的右值


我的第一个想法是,为了传递给函数,临时构造函数必须是构造函数,但更令人惊讶的是,即使使用
-fno elide构造函数
,并取消删除移动构造函数和复制构造函数,似乎也不会调用它们!这是gcc和clang中的一个bug吗

请参阅以了解错误 查看调用foo(std::move(ptr))时的奇怪行为

您没有给它一个
包装器
。因此,编译器生成一个临时变量,并使用它来构造
foo
的参数。现在,这可以省去,我们可以直接构造一个
包装器
,但是move/copy构造函数仍然需要是可访问的,即使它从未被调用过


对于C++17,这种情况不再发生。我们有,这意味着永远不会实现临时,而是直接构造参数。

您认为的确切错误是什么get@vu1p3n0x在问题中发布了它们,标题中也有“查看奇怪行为”的链接,它确实称为移动constructor@Revolver_Ocelot我弄糊涂了。。我觉得打印的声明放错地方了。Nvm这个问题很愚蠢。但是为什么从来没有调用move构造函数呢?即使使用
-fno-elide构造函数
@好奇的共构造函数是语言所必需的,但调用可以通过优化来消除。@好奇是因为即使编译器足够聪明,不需要临时调用,语言标准说适当的构造函数仍然可以访问。@Slava
-fno-elide构造函数
压制optimization@NathanOliver那么,在传递了用于抑制省略错误的标志之后,是否遵循了代码路径?因为在传递该标志时不应发生移动省略
#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));
}