给出以下代码
test.h:
#ifndef __graph_aufbau_header__
#define __graph_aufbau_header__
#include <vector>
#include <queue>
#include <string>
using namespace std;
class Knoten {
public:
unsigned int nummer;
double x_1;
double x_2;
unsigned int abstand;
Knoten(unsigned int num, double x1, double x2) : nummer(num), x_1(x1), x_2(x2), abstand(-1) {};
Knoten(Knoten&& anderer) : nummer(anderer.nummer), x_1(anderer.x_1), x_2(anderer.x_2), abstand(anderer.abstand) {};
Knoten& operator=(Knoten&& anderer) = default;
};
class Kante {
public:
unsigned int quellknotennum;
unsigned int zielknotennum;
unsigned int gewicht;
Kante(unsigned int qnum, unsigned int znum, unsigned int gew)
: quellknotennum(qnum), zielknotennum(znum), gewicht(gew)
{};
Kante(Kante&& andere)
: quellknotennum(andere.quellknotennum),
zielknotennum(andere.zielknotennum),
gewicht(andere.gewicht) {};
Kante& operator=(const Kante& andere) = default;
inline bool operator<(const Kante& kante_2){
return this->quellknotennum < kante_2.quellknotennum;
};
};
class Offset {
public:
unsigned int knoten_num;
unsigned int kanten_num;
Offset(unsigned int knnum, unsigned int kanum)
: knoten_num(knnum), kanten_num(kanum)
{};
Offset(Offset&& anderer)
: knoten_num(anderer.knoten_num), kanten_num(anderer.kanten_num) {};
Offset& operator=(Offset& anderer) = default;
};
class Graph {
public:
vector<Knoten> coordList;
vector<Kante> edgeList;
vector<Offset> edgeOffsets;
//vector<unsigned int> abstand;
Graph() : coordList(), edgeList(), edgeOffsets(){};
void knoten_einlesen(double x_1, double x_2);
void kante_einlesen(unsigned int quellknoten, unsigned int zielknoten, unsigned int gewicht);
void offset_einlesen(unsigned int nummer, unsigned int kante);
void einlesen(string quelle);
Knoten naechster_Nachbar(Knoten& knoten);
};
#endif
test.cc:
// kein iostream
#include <fstream> // benötigt für die Deklaration eines Dateistroms
#include <iostream>
#include <string>
#include <sstream> // zum Splitten
//#include <regex>
#include <cstdlib> // Zur Umwandlung von Strings in Doubles
#include <algorithm> // fuer find_if()
#include <queue>
#include <vector>
#include "test.h"
using namespace std;
void Graph::knoten_einlesen(double x_1, double x_2){
unsigned int neue_position = coordList.size();
coordList.emplace_back(neue_position, x_1, x_2);
}
void Graph::kante_einlesen(unsigned int knoten_1, unsigned int knoten_2, unsigned int gewicht){
edgeList.emplace_back(knoten_1, knoten_2, gewicht);
}
void Graph::offset_einlesen(unsigned int nummer, unsigned int kante){
edgeOffsets.emplace_back(nummer, kante);
}
void Graph::einlesen(string quelle){
ifstream datendatei(quelle);
if (datendatei.is_open()){
string aktuelle_zeile;
getline(datendatei, aktuelle_zeile);
unsigned int anzahl_knoten = stoi(aktuelle_zeile);
getline(datendatei, aktuelle_zeile);
unsigned int anzahl_kanten = stoi(aktuelle_zeile);
unsigned int nummer, position;
for(auto& knoten: coordList){
nummer = knoten.nummer;
auto erste_kante = find_if(edgeList.begin(), edgeList.end(), [nummer] (Kante kante)\
{return nummer == kante.quellknotennum;});
position = erste_kante - edgeList.begin(); // Position der ersten Kante, die mit dem Knoten verbunden ist, in edgeOffsets
offset_einlesen(nummer, position);
}
datendatei.close();
}
}
Knoten Graph::naechster_Nachbar(Knoten& knoten){
return coordList.at(edgeList.at(edgeOffsets.at(knoten.nummer).kanten_num).zielknotennum);
}
,我通过调用g++ -std=gnu++11 test.cc
收到以下错误:
test.cc: In member function 'Knoten Graph::naechster_Nachbar(Knoten&)':
test.cc:55:96: error: use of deleted function 'constexpr Knoten::Knoten(const Knoten&)'
return coordList.at(edgeList.at(edgeOffsets.at(knoten.nummer).kanten_num).zielknotennum);
^
In file included from test.cc:11:0:
test.h:10:11: note: 'constexpr Knoten::Knoten(const Knoten&)' is implicitly declared as deleted because 'Knoten' declares a move constructor or move assignment operator
class Knoten {
^~~~~~
In file included from C:/Program Files/mingw-w64/x86_64-6.2.0-win32-seh-rt_v5-rev1/mingw64/lib/gcc/x86_64-w64-mingw32/6.2.0/include/c++/bits/stl_algobase.h:71:0,
from C:/Program Files/mingw-w64/x86_64-6.2.0-win32-seh-rt_v5-rev1/mingw64/lib/gcc/x86_64-w64-mingw32/6.2.0/include/c++/bits/char_traits.h:39,
from C:/Program Files/mingw-w64/x86_64-6.2.0-win32-seh-rt_v5-rev1/mingw64/lib/gcc/x86_64-w64-mingw32/6.2.0/include/c++/ios:40,
from C:/Program Files/mingw-w64/x86_64-6.2.0-win32-seh-rt_v5-rev1/mingw64/lib/gcc/x86_64-w64-mingw32/6.2.0/include/c++/istream:38,
from C:/Program Files/mingw-w64/x86_64-6.2.0-win32-seh-rt_v5-rev1/mingw64/lib/gcc/x86_64-w64-mingw32/6.2.0/include/c++/fstream:38,
from test.cc:2:
C:/Program Files/mingw-w64/x86_64-6.2.0-win32-seh-rt_v5-rev1/mingw64/lib/gcc/x86_64-w64-mingw32/6.2.0/include/c++/bits/predefined_ops.h: In instantiation of 'bool __gnu_cxx::__ops::_Iter_pred<_Predicate>::operator()(_Iterator) [with _Iterator = __gnu_cxx::__normal_iterator<Kante*, std::vector<Kante> >; _Predicate = Graph::einlesen(std::__cxx11::string)::<lambda(Kante)>]':
C:/Program Files/mingw-w64/x86_64-6.2.0-win32-seh-rt_v5-rev1/mingw64/lib/gcc/x86_64-w64-mingw32/6.2.0/include/c++/bits/stl_algo.h:120:14: required from '_RandomAccessIterator std::__find_if(_RandomAccessIterator, _RandomAccessIterator, _Predicate, std::random_access_iterator_tag) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<Kante*, std::vector<Kante> >; _Predicate = __gnu_cxx::__ops::_Iter_pred<Graph::einlesen(std::__cxx11::string)::<lambda(Kante)> >]'
C:/Program Files/mingw-w64/x86_64-6.2.0-win32-seh-rt_v5-rev1/mingw64/lib/gcc/x86_64-w64-mingw32/6.2.0/include/c++/bits/stl_algo.h:161:23: required from '_Iterator std::__find_if(_Iterator, _Iterator, _Predicate) [with _Iterator = __gnu_cxx::__normal_iterator<Kante*, std::vector<Kante> >; _Predicate = __gnu_cxx::__ops::_Iter_pred<Graph::einlesen(std::__cxx11::string)::<lambda(Kante)> >]'
C:/Program Files/mingw-w64/x86_64-6.2.0-win32-seh-rt_v5-rev1/mingw64/lib/gcc/x86_64-w64-mingw32/6.2.0/include/c++/bits/stl_algo.h:3817:28: required from '_IIter std::find_if(_IIter, _IIter, _Predicate) [with _IIter = __gnu_cxx::__normal_iterator<Kante*, std::vector<Kante> >; _Predicate = Graph::einlesen(std::__cxx11::string)::<lambda(Kante)>]'
test.cc:44:57: required from here
C:/Program Files/mingw-w64/x86_64-6.2.0-win32-seh-rt_v5-rev1/mingw64/lib/gcc/x86_64-w64-mingw32/6.2.0/include/c++/bits/predefined_ops.h:234:11: error: use of deleted function 'constexpr Kante::Kante(const Kante&)'
{ return bool(_M_pred(*__it)); }
^~~~~~~~~~~~~~~~~~~~
In file included from test.cc:11:0:
test.h:22:11: note: 'constexpr Kante::Kante(const Kante&)' is implicitly declared as deleted because 'Kante' declares a move constructor or move assignment operator
class Kante {
^~~~~
test.cc:43:99: note: initializing argument 1 of 'Graph::einlesen(std::__cxx11::string)::<lambda(Kante)>'
auto erste_kante = find_if(edgeList.begin(), edgeList.end(), [nummer] (Kante kante)\
^
(不要错过右侧隐藏的错误)
我已经花了很多时间来解决这个问题,今天,我不知道这里出了什么问题。显然,代码在方法naechster_nachbar(..)中调用了一个隐含删除的类“Knoten”的移动构造函数 - 但我不知道为什么会发生这种情况以及如何防止相应的错误消息。
另一部分(大的,略显模糊的部分)可能是在函数einlesen(...)(lambda函数?)中的某个地方引起的,可能与第一部分的原因相同。
给定的代码无法独立编译或甚至完整且有意义;它的唯一目标是演示生成的错误消息。我无法进一步减小这个最小例子的大小。我们被迫使用C ++ 11(因此命令行选项是必须的)。
非常感谢提前!
答案 0 :(得分:3)
Knoten Graph::naechster_Nachbar(Knoten&)
按值返回,因此会尝试复制Knoten
。但它不能,因为类只有一个移动构造函数而没有复制构造函数。
有趣的是,移动构造函数实际上复制了anderer
中的所有数据,因此它可能只是一个复制构造函数。
答案 1 :(得分:2)
您已为Knoten和Kante指定了移动构造函数,这会删除默认的复制构造函数。理由是,如果你编写自己的移动构造函数,那么假设这个类需要一些非平凡的逻辑,所以如果为移动构造函数/赋值运算符提供了这个逻辑,那么常规版本也需要这个逻辑。
如果添加以下代码,您的代码将被编译:
Knoten(const Knoten& anderer) = default;
Knoten& operator=(const Knoten& anderer) = default;
和
Kante(const Kante& anderer) = default;
但我不确定默认逻辑是否适合您的课程。您还应该考虑一下,如果您真的需要自己的移动构造函数/运算符。