reference member ‘int& Mapping<int>::to’, can't use default assignment operator
-
Hallo Leute,
inzwischen habe ich zu obiger Fehlermeldung schon viel im Internet gesucht und auch das eine oder andere gefunden. So z.B. dass man in C++ einer Referenz nichts zuweisen kann, sondern diese initialisiert werden muss und anschließend nicht mehr geändert werden kann. Doch leider hilft mir dieses Wissen bei meinem konkreten Programm nicht weiter, da ich nicht sehe, wo ich was falsch mache. Ich hoffe, jemand von euch kann mir helfen.
Hier mein (wesentlicher) Code:
#include <sstream>
template<class T> class Mapping{
private:
std::string from;
T& to;
public:
Mapping(std::string& f, T& t):from(f),to(t){ }std::string getFrom(){ return from; }
T& getTo(){ return to; }
std::string toString() const{
//int bzw. double to in einen string umwandeln:
std::stringstream sstr;
sstr << to;
std::string stringTo;
sstr >> stringTo;return "( "+from+"\t->\t"+stringTo+" )";
}
};FormelParser.hpp:
...
typedef Mapping<int> intMapping;
typedef Mapping<double> doubleMapping;
typedef Mapping<class T> universeMapping;FormelParser.cpp:
#include "FormelParser.hpp"
unsigned int pos;
std::vector<Mapping<int>* > varMapping;
std::vector<Mapping<double> > *constMapping;
DdManager *mgr;
std::setstd::string *variables;...
DdNode* FormelParser::parseConstant(string cons){
double consDouble = toDouble(cons.c_str());
addToConstMapping(cons, consDouble);
return Cudd_addConst(mgr,consDouble);
}int FormelParser::getIndex(std::vector<intMapping>*& mapping, string var){
std::vector<intMapping>::iterator it;
for(it=mapping->begin(); it!=mapping->end(); ++it){
if(var.compare(it->getFrom())==0) return it->getTo();
}
return -1;
}...
DdNode* FormelParser::newVariable(int p, string s){
std::cout << "newVariable(" << s << ")" << endl;
string variable = varName(s, p); std::cout << "Variable: " << variable << endl;
pos = p+variable.length();
if(!isVariableName(variable)){
...
throw new IllegalArgumentException(err);
}
DdNode* res;
if(variables->find(variable)!=variables->end()){//Variable schon erzeugt
std::cout << "Variable schon erzeugt" << endl;
int index = getIndex(varMapping, variable);
res = Cudd_addIthVar(mgr,index); Cudd_Ref(res);
}
else{
res = Cudd_addNewVar(mgr); Cudd_Ref(res);
int index = Cudd_NodeReadIndex(res);
intMapping *newVar = new intMapping::Mapping(variable, index);
varMapping->push_back(*newVar);
variables->insert(variable);
}
return res;
}...
FormelParser::FormelParser(DdManager *manager){
pos = 0;
mgr = manager;
Cudd_EnableGarbageCollection(mgr);
varMapping = new std::vector<Mapping<int> >();
constMapping = new std::vector<Mapping<double> >();
variables = new std::setstd::string();
}std::vector<intMapping>* FormelParser::getVarMapping(){ return varMapping; }
std::vector<doubleMapping>* FormelParser::getConstMapping(){ return constMapping; }void FormelParser::addToVarMapping(string from, int to){
intMapping *var = new intMapping::Mapping(from,to);
varMapping->push_back(*var);
}void FormelParser::addToConstMapping(string from, double to){
doubleMapping *cons = new doubleMapping::Mapping(from,to);
constMapping->push_back(*cons);
}template<class T>
void FormelParser::printMappings(std::vector<universeMapping>*& mapping){
std::vector<universeMapping>::const_iterator it;
for(it=mapping->begin(); it!=mapping->end(); ++it){
std::cout << it->toString() << std::endl;
}
}template<class T> char** getNames(std::vector<Mapping<T> >*& mapping){
char *names=0;
std::vector<universeMapping>::iterator it;
unsigned int pos;
for(it=mapping->begin(), pos=0; it!=mapping->end(); ++it,++pos)
names[pos]=const_cast<char>((it->getFrom()).c_str());
return names;
}char** FormelParser::getVarNames(){
return getNames(varMapping);
}char** FormelParser::getConstNames(){
return getNames(constMapping);
}int* FormelParser::getIDs(){
int* ids=0;
std::vector<intMapping>::iterator it;
unsigned int pos;
for(it=varMapping->begin(), pos=0; it!=varMapping->end(); ++it,++pos)
ids[pos]=it->getTo();
return ids;
}Sieht jemand von euch, was ich falsch mache?
-
Ich helfe dir mal insofern, als dass ich deinen Code mal so formatiere, dass man ihn auch lesen kann. Aber: Das ist viel zu viel Code und du sagst noch nicht einmal wo der Fehler auftritt. Fasse dich kurz.
#include <sstream> template < class T > class Mapping { private: std::string from; T & to; public: Mapping(std::string & f, T & t):from(f), to(t) { } std::string getFrom() { return from; } T & getTo() { return to; } std::string toString()const { //int bzw. double to in einen string umwandeln: std::stringstream sstr; sstr << to; std::string stringTo; sstr >> stringTo; return "( " + from + "\t->\t" + stringTo + " )"; }};FormelParser.hpp:
typedef Mapping < int >intMapping; typedef Mapping < double >doubleMapping; typedef Mapping < class T > universeMapping;FormelParser.cpp:
#include "FormelParser.hpp" unsigned int pos; std::vector < Mapping < int >*>*varMapping; std::vector < Mapping < double >*>*constMapping; DdManager *mgr; std::set < std::string > *variables; DdNode * FormelParser::parseConstant(string cons) { double consDouble = toDouble(cons.c_str()); addToConstMapping(cons, consDouble); return Cudd_addConst(mgr, consDouble); } int FormelParser::getIndex(std::vector < intMapping > *&mapping, string var) { std::vector < intMapping >::iterator it; for (it = mapping->begin(); it != mapping->end(); ++it) { if (var.compare(it->getFrom()) == 0) return it->getTo(); } return -1; } DdNode * FormelParser::newVariable(int p, string s) { std::cout << "newVariable(" << s << ")" << endl; string variable = varName(s, p); std::cout << "Variable: " << variable << endl; pos = p + variable.length(); if (!isVariableName(variable)) { ...throw new IllegalArgumentException(err); } DdNode *res; if (variables->find(variable) != variables->end()) { //Variable schon erzeugt std::cout << "Variable schon erzeugt" << endl; int index = getIndex(varMapping, variable); res = Cudd_addIthVar(mgr, index); Cudd_Ref(res); } else { res = Cudd_addNewVar(mgr); Cudd_Ref(res); int index = Cudd_NodeReadIndex(res); intMapping *newVar = new intMapping::Mapping(variable, index); varMapping->push_back(*newVar); variables->insert(variable); } return res; } FormelParser::FormelParser(DdManager * manager) { pos = 0; mgr = manager; Cudd_EnableGarbageCollection(mgr); varMapping = new std::vector < Mapping < int >>(); constMapping = new std::vector < Mapping < double >>(); variables = new std::set < std::string > (); } std::vector < intMapping > *FormelParser::getVarMapping() { return varMapping; } std::vector < doubleMapping > *FormelParser::getConstMapping() { return constMapping; } void FormelParser::addToVarMapping(string from, int to) { intMapping *var = new intMapping::Mapping(from, to); varMapping->push_back(*var); } void FormelParser::addToConstMapping(string from, double to) { doubleMapping *cons = new doubleMapping::Mapping(from, to); constMapping->push_back(*cons); } template < class T > void FormelParser::printMappings(std::vector < universeMapping > *&mapping) { std::vector < universeMapping >::const_iterator it; for (it = mapping->begin(); it != mapping->end(); ++it) { std::cout << it->toString() << std::endl; } } template < class T > char **getNames(std::vector < Mapping < T > >*&mapping) { char **names = 0; std::vector < universeMapping >::iterator it; unsigned int pos; for (it = mapping->begin(), pos = 0; it != mapping->end(); ++it, ++pos) names[pos] = const_cast < char *>((it->getFrom()).c_str()); return names; } char **FormelParser::getVarNames() { return getNames(varMapping); } char **FormelParser::getConstNames() { return getNames(constMapping); } int *FormelParser::getIDs() { int *ids = 0; std::vector < intMapping >::iterator it; unsigned int pos; for (it = varMapping->begin(), pos = 0; it != varMapping->end(); ++it, ++pos) ids[pos] = it->getTo(); return ids; }
-
SeppJ schrieb:
Ich helfe dir mal insofern, als dass ich deinen Code mal so formatiere, dass man ihn auch lesen kann. Aber: Das ist viel zu viel Code und du sagst noch nicht einmal wo der Fehler auftritt. Fasse dich kurz.
Respekt, dass du dir die Arbeit machst und das ganze neu bzw. besser formatiert hast

Für die Fehlersuche wär echt nur relevanter Code und ne Kopie der Fehlermeldung mit Zeilenangabe ganz gut

Lg freeG
-
fr33g schrieb:
Respekt, dass du dir die Arbeit machst und das ganze neu bzw. besser formatiert hast

Arbeit? Welche Arbeit? Für so etwas gibt es indent
.
-
SeppJ schrieb:
Ich helfe dir mal insofern, als dass ich deinen Code mal so formatiere, dass man ihn auch lesen kann. Aber: Das ist viel zu viel Code und du sagst noch nicht einmal wo der Fehler auftritt. Fasse dich kurz.
Ok, dann versuche ich es noch einmal. (Ich hatte den Code schon gekürzt.)
#include <sstream> template < class T > class Mapping { private: std::string from; T & to; public: Mapping(std::string & f, T & t):from(f), to(t) { } std::string getFrom() { return from; } T & getTo() { return to; } std::string toString()const { //int bzw. double to in einen string umwandeln: std::stringstream sstr; sstr << to; std::string stringTo; sstr >> stringTo; return "( " + from + "\t->\t" + stringTo + " )"; }};FormelParser.hpp:
#include "Mapping.hpp"; ... typedef Mapping < int >intMapping; typedef Mapping < double >doubleMapping; typedef Mapping < class T > universeMapping; ...FormelParser.cpp:
#include "FormelParser.hpp" unsigned int pos; std::vector < Mapping < int >*>*varMapping; std::vector < Mapping < double >*>*constMapping; DdManager *mgr; std::set < std::string > *variables; DdNode * FormelParser::parseConstant(string cons) { ... addToConstMapping(cons, consDouble); ... } DdNode * FormelParser::newVariable(int p, string s) { ... DdNode *res; if (variables->find(variable) != variables->end()) { //Variable schon erzeugt ... } else { ... intMapping *newVar = new intMapping::Mapping(variable, index); ... } return res; } FormelParser::FormelParser(DdManager * manager) { pos = 0; mgr = manager; Cudd_EnableGarbageCollection(mgr); varMapping = new std::vector < Mapping < int >>(); constMapping = new std::vector < Mapping < double >>(); variables = new std::set < std::string > (); } void FormelParser::addToVarMapping(string from, int to) { intMapping *var = new intMapping::Mapping(from, to); varMapping->push_back(*var); } void FormelParser::addToConstMapping(string from, double to) { doubleMapping *cons = new doubleMapping::Mapping(from, to); constMapping->push_back(*cons); } template < class T > void FormelParser::printMappings(std::vector < universeMapping > *&mapping) { std::vector < universeMapping >::const_iterator it; for (it = mapping->begin(); it != mapping->end(); ++it) { std::cout << it->toString() << std::endl; } }so, ich hoffe, das ist jetzt nicht mehr zu lange und dennoch sind die wesentlichen Dinge dabei.
Und hier jetzt noch die Fehlermeldung:
In file included from FormelParser.hpp:6, #include "Mapping.hpp"
from FormelParser.cpp:1:
Mapping.hpp: In member function ‘Mapping<int>& Mapping<int>::operator=(const Mapping<int>&)’:
Mapping.hpp:7: instantiated from ‘void std::vector<_Tp, _Alloc>::_M_insert_aux(__gnu_cxx::__normal_iterator<typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type::pointer, std::vector<_Tp, _Alloc> >, const _Tp&) [with _Tp = Mapping<int>, _Alloc = std::allocator<Mapping<int> >]’
/usr/include/c++/4.4/bits/stl_vector.h:741: instantiated from ‘void std::vector<_Tp, _Alloc>::push_back(const _Tp&) [with _Tp = Mapping<int>, _Alloc = std::allocator<Mapping<int> >]’
FormelParser.cpp:199: *varMapping->push_back(newVar); instantiated from here
Mapping.hpp:7: error: non-static reference member ‘int& Mapping<int>::to’, can't use default assignment operator
In file included from /usr/include/c++/4.4/vector:69,
from FormelParser.hpp:7,
from FormelParser.cpp:1:
/usr/include/c++/4.4/bits/vector.tcc: In member function ‘void std::vector<_Tp, _Alloc>::_M_insert_aux(__gnu_cxx::__normal_iterator<typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type::pointer, std::vector<_Tp, _Alloc> >, const _Tp&) [with _Tp = Mapping<int>, _Alloc = std::allocator<Mapping<int> >]’:
/usr/include/c++/4.4/bits/vector.tcc:312: note: synthesized method ‘Mapping<int>& Mapping<int>::operator=(const Mapping<int>&)’ first required here
In file included from FormelParser.hpp:6, #include "Mapping.hpp"
from FormelParser.cpp:1:
Mapping.hpp: In member function ‘Mapping<double>& Mapping<double>::operator=(const Mapping<double>&)’:
Mapping.hpp:7: instantiated from ‘void std::vector<_Tp, _Alloc>::_M_insert_aux(__gnu_cxx::__normal_iterator<typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type::pointer, std::vector<_Tp, _Alloc> >, const _Tp&) [with _Tp = Mapping<double>, _Alloc = std::allocator<Mapping<double> >]’
/usr/include/c++/4.4/bits/stl_vector.h:741: instantiated from ‘void std::vector<_Tp, _Alloc>::push_back(const _Tp&) [with _Tp = Mapping<double>, _Alloc = std::allocator<Mapping<double> >]’
FormelParser.cpp:50: instantiated from here
Mapping.hpp:7: error: non-static reference member ‘double& Mapping<double>::to’, can't use default assignment operator
In file included from /usr/include/c++/4.4/vector:69,
from FormelParser.hpp:7, #include <vector>
from FormelParser.cpp:1:
/usr/include/c++/4.4/bits/vector.tcc: In member function ‘void std::vector<_Tp, _Alloc>::_M_insert_aux(__gnu_cxx::__normal_iterator<typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type::pointer, std::vector<_Tp, _Alloc> >, const _Tp&) [with _Tp = Mapping<double>, _Alloc = std::allocator<Mapping<double> >]’:
/usr/include/c++/4.4/bits/vector.tcc:312: note: synthesized method ‘Mapping<double>& Mapping<double>::operator=(const Mapping<double>&)’ first required here
-
Das Problem lässt sich auf folgendes kürzen:
#include <vector> struct foo { int& ref; explicit foo(int& r) : ref(r) {} }; void bar(std::vector<foo> const& x); void wontwork() { int test = 42; std::vector<foo> v; v.push_back(foo(test)); bar(v); }ref, ein nicht-statisches Element vonfoo, ist eine Referenz. Deswegen generiert der Compiler keinen Zuweisungsoperator für foo. Umvector<T>benutzen zu können, mussTaber einen Zuweisungsoperator besitzen. Du missachtest also die Typ-Bedingungen vonstd::vector<>.Änderst Du es so ab:
#include <vector> struct foo { int* ptr; explicit foo(int& r) : ptr(&r) {} }; void bar(std::vector<foo> const& x); void wontwork() { int test = 42; std::vector<foo> v; v.push_back(foo(test)); bar(v); }wird es ohne Probleme kompilieren; denn hier weiß der Compiler, wie er einen Zuweisungsoperator automatisch generieren kann. Alternativ kannst Du einen eigenen Zuweisungsoperator definieren. Das wäre dann sinnvoll, wenn Deine Klasse sich selbst wie eine Art C++-Referenz verhalten soll. Ich denke aber nicht, dass es das ist, was Du wolltest.
Möglicherweise gibt es für das, was Du machen willst, ein viel besseres Design. Eines, was nicht so stark Java-beeinflusst ist.
Warum hältst Du es für nötig Referenzen bzw Zeiger zu speichern in Deiner Klasse?BTW: Ich hoffe Dir ist klar, dass C++ die Objekte wie "normale Variablen" behandelt und einem nicht wie Java eine Indirektion (referenz<->objekt) aufzwingt.
kk
-
Das ist viel Code, den man aber nicht übersetzen kann => man kann den Fehler selber nicht nachstellen, dir zu helfen ist schwierig. Wenn jemand Hilfe will, könnte man schon etwas mehr Mitarbeit erwarten.
Warum ist dein to in Mapping eine Referenz?
In
void FormelParser::addToVarMapping(string from, int to) { intMapping *var = new intMapping::Mapping(from, to); varMapping->push_back(*var); }übergibst du einen Parameter, dessen Adresse dann gespeichert wird. Der ist aber nach verlassen der Funktion nicht mehr vorhanden.
Welchen Sinn soll das new hier haben, außer dass du ein memory leak implementiert hast?