1

i have a struct "Material" which has a referencetype of Item& Item is a baseclass for many different Materials who can appear in a list. The struct also has an integer variable and also a QString variable. Those two are just give the amount to be used and a String of what type item must be casted back.

struct Material
{
    int amount;
    Item& item;
    QString itemtype;
    Material(int myamount,Item& myitem,QString myitemtype) : amount(myamount),item(myitem),itemtype(myitemtype){}
};

As i have read here: initialize struct contain references to structs

to have a reference sitting inside of a struct one need to define a constructor within the struct. as you can see in the upper Material struct.

Now when i try to retrive the reference of that, like here:

QList<Material> Mats = bp.Materials();
for(int i=0;i<Mats.count();i++)
{
      Item& item = Mats[i].item;
}

i allways get an error like "use of deleted function 'Material& Material::operator=(const Material&)"

I also tried already to define such a operator= but obviously if i try to return the rvalue which is const i can't do this because the lvalue is not const. and if i make a new instance of Material it is going to be an implicit copy constructor.

My Question: What do i miss here?

On the wish to make a reproduceable example, i may got to the problem. I have no solution for my one just yet but an idea what may have caused this:

#include <QCoreApplication>
#include <QList>

struct Kram
{
   QString& text;
   Kram(QString& s): text(s) {}
};



int main(int argc, char *argv[])
{
   QCoreApplication a(argc, argv);

   QString mytext= "Hello, World!";
   Kram k(mytext);

   QList<Kram> liste;
   liste.append(k);

   for(int i=0; i<liste.count();i++)
   {
      QString& anothertext = liste[i].text;
   }

return a.exec();

}

When i compile this he tells me the exact same error message about the "Kram" struct. But this only appears if you do the struct in a Qlist and then try to get the reference inside of the struct out.

just to mention the second error message is in both cases thisone:

C:\Users\Rolf\Documents\Testprojekt\main.cpp:4: Fehler: non-static reference member 'QString& Kram::text', can't use default assignment operator

12
  • 1
    What does bp.Materials().values() return? If it's a reference or const reference then this is the type you have to use for your local variable Mats. Otherwise, you're lost. As you have it currently, you copy the QList<Material>, and this seems to make a deep copy (copying all the list elements as well). Commented Jun 30, 2022 at 16:24
  • Who is owning the Item instances that you keep references to?
    – Ted Lyngmo
    Commented Jun 30, 2022 at 16:28
  • 2
    Btw. you cannot write a (sane) copy assignment operator for a struct with a reference member. In this case, you have to turn it into a pointer or try to prevent any copy assignment. (Sometimes, this can be intended e.g. for resource management.) Commented Jun 30, 2022 at 16:35
  • 2
    At least, I cleared up my mind concerning the implicit sharing... :-) Even with implicit sharing, the QList must be able to perform a deep copy (when copy-on-write happens). Hence, there is in fact somewhere in the QList a copy assignment used for the elements (of type Material in your case). And this doesn't compile as the compiler cannot create one for your Material due to the Material::item member which is a reference. Commented Jun 30, 2022 at 16:39
  • 1
    please post a minimal reproducible example Commented Jun 30, 2022 at 16:58

1 Answer 1

1

For all who stumble on this, i will post my fixed example code. But i highly recommend to read the comments from Scheff's Cat and sigma below my question. Because they give you some really important infos why this is happening. I my self will consider the idea of sigma to use the std::unique_ptr for my code.

eyeball in the following code that now the struct holds a pointer but the constructer gets a reference so that there is no nullpointer. but still the object here in the main code can be assigned normaly meaning no pointer involved there.

here is the code:

#include <QCoreApplication>
#include <QList>

struct Kram
{
   QString* text;
   Kram(QString& s): text(&s) {}
};



int main(int argc, char *argv[])
{
   QCoreApplication a(argc, argv);

   QString mytext= "Hello, World!";
   Kram k(mytext);

   QList<Kram> liste;
   liste.append(k);

   for(int i=0; i<liste.count();i++)
   {
      QString* anothertext = liste[i].text;
   }

   return a.exec();
}

thank you all for helping me finding out of this maze

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.