对不起这里的菜鸟问题,但我甚至不知道在谷歌搜索什么。我在移动语义上尝试了一些文档,但我仍然无法解决我的问题。
所以如果有人能给我一些线索,我会非常感激。
关于代码:
graph.hpp:
#ifndef GRAPH_HPP
#define GRAPH_HPP
#include <cstdlib>
#include <unordered_map>
#include <vector>
#include <string>
template<typename T, typename U>
class Link;
template<typename T, typename U>
class Node;
namespace graph
{
template<typename T, typename U>
class Link
{
public:
Link() = default;
Link(U&& data, T& node) : _data(data), _endNode(node) {}
~Link() = default;
private:
U _data;
Node<T, U>& _endNode;
};
template<typename T, typename U>
class Node
{
public:
Node() = default;
Node(T&& data) : _data(data) {};
~Node() = default;
private:
T _data;
std::vector<Link<T, U>> _links;
};
template<typename K, typename T, typename U>
class Graph
{
public:
Graph() = default;
~Graph() = default;
private:
size_t _nbNode;
std::unordered_map<K, Node<T, U>> _nodes;
public:
#include "graph.tpp"
};
}
#endif
graph.tpp:
void add_Link(const K& key1,
const K& key2,
U&& linkInfo)
{
if (!_nodes.count(key1)
|| !_nodes.count(key2))
throw "Key doesn't exist!";
Link<T, U> newLink(linkInfo, _nodes[key2]);
_nodes[key1].links.push_back(newLink);
}
void add_Node(K& key, T&& elem)
{
Node<T, U> newNode(std::move(elem));
_nodes[key] = std::move(newNode);
}
main.cpp中:
#include "graph.hpp"
#include <string>
int main()
{
std::string name("name");
graph::Graph<std::string, std::string, std::string> graph;
graph.add_Node(name, "lol");
return 0;
}
我只是想在unordered_map中添加一个带移动的新元素。但它只是说我:
clang++ -Wall -Wextra -std=c++14 -O2 -march=native -s -fomit-frame-pointer -c src/test.cpp -o obj/test.o -I ./src/include -I ./src/template/
clang: warning: argument unused during compilation: '-s'
In file included from src/test.cpp:1:
In file included from ./src/include/graph.hpp:15:
In file included from /usr/bin/../lib64/gcc/x86_64-unknown-linux-gnu/4.9.2/../../../../include/c++/4.9.2/unordered_map:41:
In file included from /usr/bin/../lib64/gcc/x86_64-unknown-linux-gnu/4.9.2/../../../../include/c++/4.9.2/tuple:39:
In file included from /usr/bin/../lib64/gcc/x86_64-unknown-linux-gnu/4.9.2/../../../../include/c++/4.9.2/array:38:
In file included from /usr/bin/../lib64/gcc/x86_64-unknown-linux-gnu/4.9.2/../../../../include/c++/4.9.2/stdexcept:39:
In file included from /usr/bin/../lib64/gcc/x86_64-unknown-linux-gnu/4.9.2/../../../../include/c++/4.9.2/string:40:
In file included from /usr/bin/../lib64/gcc/x86_64-unknown-linux-gnu/4.9.2/../../../../include/c++/4.9.2/bits/char_traits.h:39:
/usr/bin/../lib64/gcc/x86_64-unknown-linux-gnu/4.9.2/../../../../include/c++/4.9.2/bits/stl_algobase.h:336:18: error: object of type 'graph::Link<std::basic_string<char>, std::basic_string<char> >' cannot be assigned because its copy
assignment operator is implicitly deleted
*__result = *__first;
^
/usr/bin/../lib64/gcc/x86_64-unknown-linux-gnu/4.9.2/../../../../include/c++/4.9.2/bits/stl_algobase.h:396:36: note: in instantiation of function template specialization 'std::__copy_move<false, false,
std::random_access_iterator_tag>::__copy_m<const graph::Link<std::basic_string<char>, std::basic_string<char> > *, graph::Link<std::basic_string<char>, std::basic_string<char> > *>' requested here
_Category>::__copy_m(__first, __last, __result);
^
/usr/bin/../lib64/gcc/x86_64-unknown-linux-gnu/4.9.2/../../../../include/c++/4.9.2/bits/stl_algobase.h:432:23: note: in instantiation of function template specialization 'std::__copy_move_a<false, const graph::Link<std::basic_string<char>,
std::basic_string<char> > *, graph::Link<std::basic_string<char>, std::basic_string<char> > *>' requested here
return _OI(std::__copy_move_a<_IsMove>(std::__niter_base(__first),
^
/usr/bin/../lib64/gcc/x86_64-unknown-linux-gnu/4.9.2/../../../../include/c++/4.9.2/bits/stl_algobase.h:464:20: note: in instantiation of function template specialization 'std::__copy_move_a2<false, __gnu_cxx::__normal_iterator<const
graph::Link<std::basic_string<char>, std::basic_string<char> > *, std::vector<graph::Link<std::basic_string<char>, std::basic_string<char> >, std::allocator<graph::Link<std::basic_string<char>, std::basic_string<char> > > > >,
__gnu_cxx::__normal_iterator<graph::Link<std::basic_string<char>, std::basic_string<char> > *, std::vector<graph::Link<std::basic_string<char>, std::basic_string<char> >, std::allocator<graph::Link<std::basic_string<char>,
std::basic_string<char> > > > > >' requested here
return (std::__copy_move_a2<__is_move_iterator<_II>::__value>
^
/usr/bin/../lib64/gcc/x86_64-unknown-linux-gnu/4.9.2/../../../../include/c++/4.9.2/bits/vector.tcc:206:27: note: in instantiation of function template specialization 'std::copy<__gnu_cxx::__normal_iterator<const
graph::Link<std::basic_string<char>, std::basic_string<char> > *, std::vector<graph::Link<std::basic_string<char>, std::basic_string<char> >, std::allocator<graph::Link<std::basic_string<char>, std::basic_string<char> > > > >,
__gnu_cxx::__normal_iterator<graph::Link<std::basic_string<char>, std::basic_string<char> > *, std::vector<graph::Link<std::basic_string<char>, std::basic_string<char> >, std::allocator<graph::Link<std::basic_string<char>,
std::basic_string<char> > > > > >' requested here
std::_Destroy(std::copy(__x.begin(), __x.end(), begin()),
^
./src/include/graph.hpp:40:10: note: in instantiation of member function 'std::vector<graph::Link<std::basic_string<char>, std::basic_string<char> >, std::allocator<graph::Link<std::basic_string<char>, std::basic_string<char> > >
>::operator=' requested here
class Node
^
src/test.cpp:9:9: note: in instantiation of member function 'graph::Graph<std::basic_string<char>, std::basic_string<char>, std::basic_string<char> >::add_Node' requested here
graph.add_Node(name, "lol");
^
./src/include/graph.hpp:36:15: note: copy assignment operator of 'Link<std::basic_string<char>, std::basic_string<char> >' is implicitly deleted because field '_endNode' is of reference type
'Node<std::basic_string<char>, std::basic_string<char> > &'
Node<T, U>& _endNode;
^
In file included from src/test.cpp:1:
In file included from ./src/include/graph.hpp:15:
In file included from /usr/bin/../lib64/gcc/x86_64-unknown-linux-gnu/4.9.2/../../../../include/c++/4.9.2/unordered_map:41:
In file included from /usr/bin/../lib64/gcc/x86_64-unknown-linux-gnu/4.9.2/../../../../include/c++/4.9.2/tuple:39:
In file included from /usr/bin/../lib64/gcc/x86_64-unknown-linux-gnu/4.9.2/../../../../include/c++/4.9.2/array:38:
In file included from /usr/bin/../lib64/gcc/x86_64-unknown-linux-gnu/4.9.2/../../../../include/c++/4.9.2/stdexcept:39:
In file included from /usr/bin/../lib64/gcc/x86_64-unknown-linux-gnu/4.9.2/../../../../include/c++/4.9.2/string:40:
In file included from /usr/bin/../lib64/gcc/x86_64-unknown-linux-gnu/4.9.2/../../../../include/c++/4.9.2/bits/char_traits.h:39:
/usr/bin/../lib64/gcc/x86_64-unknown-linux-gnu/4.9.2/../../../../include/c++/4.9.2/bits/stl_algobase.h:336:18: error: object of type 'graph::Link<std::basic_string<char>, std::basic_string<char> >' cannot be assigned because its copy
assignment operator is implicitly deleted
*__result = *__first;
^
/usr/bin/../lib64/gcc/x86_64-unknown-linux-gnu/4.9.2/../../../../include/c++/4.9.2/bits/stl_algobase.h:396:36: note: in instantiation of function template specialization 'std::__copy_move<false, false,
std::random_access_iterator_tag>::__copy_m<graph::Link<std::basic_string<char>, std::basic_string<char> > *, graph::Link<std::basic_string<char>, std::basic_string<char> > *>' requested here
_Category>::__copy_m(__first, __last, __result);
^
/usr/bin/../lib64/gcc/x86_64-unknown-linux-gnu/4.9.2/../../../../include/c++/4.9.2/bits/stl_algobase.h:432:23: note: in instantiation of function template specialization 'std::__copy_move_a<false, graph::Link<std::basic_string<char>,
std::basic_string<char> > *, graph::Link<std::basic_string<char>, std::basic_string<char> > *>' requested here
return _OI(std::__copy_move_a<_IsMove>(std::__niter_base(__first),
^
/usr/bin/../lib64/gcc/x86_64-unknown-linux-gnu/4.9.2/../../../../include/c++/4.9.2/bits/stl_algobase.h:464:20: note: in instantiation of function template specialization 'std::__copy_move_a2<false, graph::Link<std::basic_string<char>,
std::basic_string<char> > *, graph::Link<std::basic_string<char>, std::basic_string<char> > *>' requested here
return (std::__copy_move_a2<__is_move_iterator<_II>::__value>
^
/usr/bin/../lib64/gcc/x86_64-unknown-linux-gnu/4.9.2/../../../../include/c++/4.9.2/bits/vector.tcc:211:13: note: in instantiation of function template specialization 'std::copy<graph::Link<std::basic_string<char>, std::basic_string<char> >
*, graph::Link<std::basic_string<char>, std::basic_string<char> > *>' requested here
std::copy(__x._M_impl._M_start, __x._M_impl._M_start + size(),
^
./src/include/graph.hpp:40:10: note: in instantiation of member function 'std::vector<graph::Link<std::basic_string<char>, std::basic_string<char> >, std::allocator<graph::Link<std::basic_string<char>, std::basic_string<char> > >
>::operator=' requested here
class Node
^
src/test.cpp:9:9: note: in instantiation of member function 'graph::Graph<std::basic_string<char>, std::basic_string<char>, std::basic_string<char> >::add_Node' requested here
graph.add_Node(name, "lol");
^
./src/include/graph.hpp:36:15: note: copy assignment operator of 'Link<std::basic_string<char>, std::basic_string<char> >' is implicitly deleted because field '_endNode' is of reference type
'Node<std::basic_string<char>, std::basic_string<char> > &'
Node<T, U>& _endNode;
^
2 errors generated.
Makefile:43: recipe for target 'obj/test.o' failed
make: *** [obj/test.o] Error 1
抱歉,祝你有个美好的一天。
答案 0 :(得分:2)
好。问题出在这一行:
_nodes[key] = std::move(newNode);
您正在尝试移动 - 分配Node<T, U>
。但是,Node
将没有隐式声明为默认的移动赋值运算符,因为存在用户声明的析构函数:
~Node() = default;
因此,该行实际上调用了Node<T, U>
的 copy 赋值运算符,该运算符执行成员方式的副本。 Node<T, U>
的其中一个成员属于std::vector<Link<T, U>>
,其中Link<T, U>
有一个成员变量作为参考。引用不可复制,因此隐式删除了复制赋值运算符。因此,没有找到复制赋值运算符,因此该行格式不正确。
虽然引用也不是可移动赋值的,但vector<Link<T,U>>
是可移动赋值的,因此最简单的解决方案是删除将析构函数声明为默认值的行:
//~Node() = default;
这样,编译器将隐式声明默认的移动构造函数/赋值,并且此代码将执行您期望的操作。并编译。
旁注,这是一个非常糟糕的主意:
public:
#include "graph.tpp"
};