1

It is necessary to receive data in the format described in the code, but the problem is with the operation of string variables. What can be done to avoid mistakes?

class Class1
{
public:
    Class1() = delete ;
    const static int x = 1;
    static struct ZZ {
        const static int z1 = 1;
        const static QString z2 = "word";
    } z;
};

int main(int argc, char* argv[])
{
    QCoreApplication a(argc, argv);
    qDebug() << Class1::z.z2;
    return a.exec();
}

Errors:

class1.h:13: ошибка: in-class initialization of static data member 'const QString Class1::ZZ::z2' of non-literal type
         const static QString z2 = "word";
                              ^~
class1.h:13: ошибка: call to non-constexpr function 'QString::QString(const char*)'
         const static QString z2 = "word";
                                   ^~~~~~

Source github.com

0

1 Answer 1

1

Disclaimer:

My first impression was that this code abuses class and struct for what namespace was actually invented for.

This said, the answer focusses on the technical issues with the static data members in OPs code.


To reproduce the issue, I made the following similar example:

#include <iostream>
#include <string>

class Class1
{
public:
    Class1() = delete ;
    const static int x = 1;
    static struct ZZ {
        static const int z1 = 1;
        static const std::string z2 = "word";
    } z;
};

int main(int argc, char* argv[])
{
    std::cout << Class1::z.z2;
}

Output:

main.cpp:11:34: error: in-class initialization of static data member 'const string Class1::ZZ::z2' of non-literal type
   11 |         static const std::string z2 = "word";
      |                                  ^~
main.cpp:11:39: error: temporary of non-literal type 'const string' {aka 'const std::__cxx11::basic_string<char>'} in a constant expression
   11 |         static const std::string z2 = "word";
      |                                       ^~~~~~

Live Demo on coliru

IMHO, this is close enough to the issue of OP.

TL;DR: The problem is that static member variables must be either explicitly defined (non-inlined) or remarked as inline.

So, my fix would look like this:

#include <iostream>
#include <string>

class Class1
{
public:
    Class1() = delete ;
    const static int x = 1;
    inline static struct ZZ {
        static const int z1 = 1;
        inline static const std::string z2 = "word";
    } z = ZZ{};
};

int main(int argc, char* argv[])
{
    std::cout << Class1::x << '\n'
      << Class1::z.z1 << '\n'
      << Class1::z.z2 << '\n';
}

Output:

1
1
word

Live Demo on coliru

Note:

While the inline is necessary for struct ZZ and std::string, it can be left out for integral types. Hence, static const int z1 = 1; will be accepted without complaints (without prefixing it with inline).

Further reading:

Static data members on cppreference.com


For the comparison, the same code made working without inline:

#include <iostream>
#include <string>

class Class1
{
public:
    Class1() = delete ;
    const static int x = 1;
    static struct ZZ {
        static const int z1 = 1;
        static const std::string z2;
    } z;
};

//Class1::ZZ Class1::z;
const std::string Class1::ZZ::z2 = "word";

int main(int argc, char* argv[])
{
    std::cout << Class1::x << '\n'
      << Class1::z.z1 << '\n'
      << Class1::z.z2 << '\n';
}

Output:

1
1
word

Live Demo on coliru

Note:

About const Class1::ZZ Class1::z;, I was not quite sure. The missing definition might be left out as Class1::z is never used itself.

To check this out, I modified the sample again:

#include <iostream>
#include <string>

class Class1
{
public:
    Class1() = delete ;
    const static int x = 1;
    static struct ZZ {
        static const int z1 = 1;
        static const std::string z2;
    } z;
};

Class1::ZZ Class1::z;
const std::string Class1::ZZ::z2 = "word";

std::ostream& operator << (std::ostream &out, const Class1::ZZ &z)
{
  return out << z.z1 << ", " << z.z2;
}

int main(int argc, char* argv[])
{
    std::cout << Class1::x << '\n'
      << Class1::z << '\n'
      << Class1::z.z1 << '\n'
      << Class1::z.z2 << '\n';
}

Output:

1
1, word
1
word

Live Demo on coliru

Note:

Commenting the definition of Class1::z (like in the previous sample) results in a link error.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.