【发布时间】:2020-03-23 22:53:52
【问题描述】:
我正在使用 ncurses 实现我的哲学家就餐问题的版本,但在初始化 Fork 对象的向量时遇到了问题。
#include <vector>
#include <mutex>
#include <ncurses.h>
...
struct Fork
{
Fork(WINDOW *fork_window) : fork_window(fork_window) {}
std::mutex m;
WINDOW *fork_window;
};
std::vector<WINDOW *> fork_windows; // properly populated later
std::vector<Fork> forks;
...
for (int i = 0; i < num_of_phils; i++)
{
forks.emplace_back(Fork(fork_windows[i]));
}
我想知道我的错误是什么(我对现代 C++ 没有那么丰富的经验)。 Fork 中的初始化列表是错误的还是 std::mutex 成员导致了问题?我以类似的方式成功填充了另一个向量,但另一个结构没有std::mutex 成员,只有WINDOW * 和三个ints。
终端里的错误很长,说:
error: use of deleted function ‘Fork::Fork(Fork&&)’,
...
note: ‘Fork::Fork(Fork&&)’ is implicitly deleted because the default definition would be ill-formed:
这是我第一次看到这样的错误,谷歌搜索也没有帮助,因为我在任何地方都没有找到类似的案例。
【问题讨论】:
-
您正在尝试
emplace和vector中的对象,这需要移动构造函数,但您没有,因此您得到error: use of deleted function ‘Fork::Fork(Fork&&)’。解决方案:创建移动构造函数 -
@nick
std::mutex不可移动,因此在按原样定义Fork的情况下无法创建移动构造函数。 -
@PaulSanders 假设他想要移动他从未声称想要移动的
mutex。如果mutex用于某些内部事物(例如多个线程与Window*混淆),则获得一个新的mutex就可以了。 -
@PaulSanders 我并不是说您的解决方案是错误的或坏的,我只是说他的问题中没有任何内容表明他实际上 需要 移动那个@ 987654339@。这意味着实现移动构造函数将消除该错误。当然,在这种情况下有最佳实践,例如 5 规则,但这只会增加两个函数,其中一个他可能无论如何都需要(析构函数),他可能已经发布了一个 minimal 示例,其中为简单起见,已将其删除。
-
@PaulSanders 当然是:
Fork(Fork&& f){ fork_window = f.fork_window; f.fork_window = nullptr; }这会将 fork 窗口指针移到上方,将另一个指针设为空,并为新对象构造一个新的mutex。复制运算符也是如此,但这看起来像是不应该被复制的类。
标签: c++ vector struct constructor initializer-list