Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Different ways of initializing an object inside of a structure

I have following class:

// NetworkManager.hpp
class NetworkManager : public QObject {
    Q_OBJECT

public:
    NetworkManager(QHostAddress const& address, quint16 port);

private:
    QHostAddress const& _address;
    quint16 const _port;
};

// NetworkManager.cpp
NetworkManager(QHostAddress const& address, quint16 const port)
    : _address(address)
    , _port(port)
{
}

This class included in a structure:

struct Context {
    NetworkManager networkManager
};

I initialize this structure like this:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

class A {
public:
    A() : _context({{QHostAddress::SpecialAddress::LocalHost, 1337}})
    {
    }

private:
    Context _context;
};

The problem is when the structure is getting initialized, it calls NetworkManager copy constructor, which is deleted by default, because it inherits QObject. But when I use different initialization, _context{{QHostAddress::SpecialAddress::LocalHost, 1337}}, everything works fine. Why does it happen?

I use Clang compiler and C++20 standard.

>Solution :

The issue is caused by the difference in the initializer list syntax between the two initializations:

A() : _context({{QHostAddress::SpecialAddress::LocalHost, 1337}})

and

A() : _context{{QHostAddress::SpecialAddress::LocalHost, 1337}}

In the first case, the outer curly braces {} create a new inner initializer list, while in the second case they are part of the same initializer list as the outer initializer list. This means that in the first case, the NetworkManager constructor is being called with a single argument, which is an initializer list, while in the second case, it is being called with two arguments, which are the QHostAddress and quint16 values.

Since the NetworkManager constructor takes two arguments, the first initialization will try to call the copy constructor, which is deleted by default because NetworkManager inherits from QObject. This causes a compile error.

On the other hand, the second initialization is correct because it passes the correct number of arguments to the NetworkManager constructor.

To fix the issue, you can either use the second initialization syntax, or define a custom copy constructor for NetworkManager to allow it to be copied.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading