gpt4 book ai didi

c++ - 在 std::pair 中存储不可复制(但可 move )的对象

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:57:00 29 4
gpt4 key购买 nike

我正在尝试将不可复制(但可 move )的对象存储在 std::pair 中,如下所示:

#include <utility>

struct S
{
S();
private:
S(const S&);
S& operator=(const S&);
};

int main()
{
std::pair<int, S> p{0, S()};
return 0;
}

但是我在使用 gcc 4.6 时遇到以下编译器错误:

In file included from include/c++/4.6.0/bits/move.h:53:0,
from include/c++/4.6.0/bits/stl_pair.h:60,
include/c++/4.6.0/utility:71,
from src/test.cpp:1:
include/c++/4.6.0/type_traits: In instantiation of 'const bool std::__is_convertible_helper<S, S, false>::__value':
include/c++/4.6.0/type_traits:789:12: instantiated from 'std::is_convertible<S, S>'
src/test.cpp:13:31: instantiated from here
src/test.cpp:7:5: error: 'S::S(const S&)' is private
include/c++/4.6.0/type_traits:782:68: error: within this context
In file included from include/c++/4.6.0/utility:71:0,
from src/test.cpp:1:
src/test.cpp: In constructor 'std::pair<_T1, _T2>::pair(_U1&&, const _T2&) [with _U1 = int, <template-parameter-2-2> = void, _T1 = int, _T2 = S]':
src/test.cpp:13:31: instantiated from here
src/test.cpp:7:5: error: 'S::S(const S&)' is private
include/c++/4.6.0/bits/stl_pair.h:121:45: error: within this context

编译器似乎正在尝试调用 std::pair<_T1, _T2>::pair(_U1&&, const _T2&)构造函数,这当然是有问题的。编译器不应该调用 std::pair<_T1, _T2>::pair(_U1&&, _U2&&)构造函数代替?这是怎么回事?

编辑:好的,我知道提供显式 move 构造函数可以解决问题,但我还是有点困惑。

假设我通过继承 boost::noncopyable 使类不可复制而不是声明我自己的私有(private)复制构造函数。

以下工作正常,表明 move 构造函数隐式生成的:

#include <boost/noncopyable.hpp>

struct S : boost::noncopyable
{
};

void f(S&&)
{

}

int main()
{
f(S());
return 0;
}

但是,对于 std::pair它仍然不起作用:

#include <utility>
#include <boost/noncopyable.hpp>

struct S : boost::noncopyable
{
};

int main()
{
std::pair<int, S> p{0, S()};
return 0;
}

错误:

In file included from include/c++/4.6.0/utility:71:0,
from src/test.cpp:1:
/include/c++/4.6.0/bits/stl_pair.h: In constructor 'std::pair<_T1, _T2>::pair(_U1&&, const _T2&) [with _U1 = int, <template-parameter-2-2> = void, _T1 = int, _T2 = S]':
src/test.cpp:16:31: instantiated from here
/include/c++/4.6.0/bits/stl_pair.h:121:45: error: use of deleted function 'S::S(const S&)'
src/test.cpp:4:8: error: 'S::S(const S&)' is implicitly deleted because the default definition would be ill-formed:
boost/boost/noncopyable.hpp:27:7: error: 'boost::noncopyable_::noncopyable::noncopyable(const boost::noncopyable_::noncopyable&)' is private
src/test.cpp:4:8: error: within this context

此外,添加 = default -ed 默认构造函数和 move 构造函数没有帮助!

#include <utility>
#include <boost/noncopyable.hpp>

struct S : boost::noncopyable
{
S() = default;
S(S&&) = default;
};

int main()
{
std::pair<int, S> p{0, S()};
return 0;
}

我得到了同样的错误!我必须自己明确给出 move 构造函数的定义,如果类有很多成员,这会很烦人:

#include <utility>
#include <boost/noncopyable.hpp>

struct S : boost::noncopyable
{
S() = default;
S(S&&) {}
};

int main()
{
std::pair<int, S> p{0, S()};
return 0;
}

最佳答案

您需要提供一个 move 构造函数。以下编译没有错误。

#include <utility>

struct S
{
S() {}
S(S&&) {}
S& operator=(S&&) {}

S(const S&) =delete;
S& operator=(const S&) =delete;
};

int main()
{
std::pair<int, S> p{0, S()};
return 0;
}


编辑:

似乎如果您从另一个类(或结构)继承,那么基类需要声明一个 move 构造函数。我认为这是因为如果您默认 派生类的 move 构造函数,它会尝试 move 基础对象但失败了。

这是定义 move 构造函数的编辑过的 boost::noncopyable

#include <utility>

namespace boost {

namespace noncopyable_ // protection from unintended ADL
{
class noncopyable
{
protected:
noncopyable() {}
noncopyable(noncopyable&&) {};
~noncopyable() {}
private: // emphasize the following members are private
noncopyable( const noncopyable& );
const noncopyable& operator=( const noncopyable& );
};
}

typedef noncopyable_::noncopyable noncopyable;

} // namespace boost

struct S : boost::noncopyable
{
S() = default;
S(S&&) = default;

S& operator=(S&&) {}
};

int main()
{
std::pair<int, S> p{0, S()};
return 0;
}

关于c++ - 在 std::pair 中存储不可复制(但可 move )的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6810629/

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