0

I'm trying to create static, constant member for a class. For now, I have this function based on C# way:

class Question : public QObject
{
    Q_OBJECT
    friend class Answer;
public:
    static const QMap<QString /*name*/, QPair<QList<quint8> /*data*/, qint32 /*answerSize*/>> questionMap()
    {
        return {
            {
                "check digit",
                {
                    {
                        0xF0, 0xC0, 0x4F
                    },
                    3
                }
            },
            {
                "line detect",
                {
                    {
                        0xF0, 0xE0, 0x2F
                    },
                    79
                }
            }
        };
    }
    static const Question& createQuestion(const QString& questionName) {
        Question* question = new Question(questionName,
                                          Question::questionMap()[questionName].first,
                                          Question::questionMap()[questionName].second);
        return *question;
    }

I wish to have something more like this:

static const QMap<QString /*name*/, QPair<QList<quint8> /*data*/, qint32 /*answerSize*/>> questionMap =
    {
        {
            "check digit",
            {
                {
                    0xF0, 0xC0, 0x4F
                },
                3
            }
        },
        {
            "line detect",
            {
                {
                    0xF0, 0xE0, 0x2F
                },
                79
            }
        }
    };

as I'm not sure how the first approach looks in terms of memory management... is this function called only once and there is no difference between two ideas or the object returned from the first function is created over and over again and it's more efficient to use the second approach? Anyway, when I'm trying to use value, it goes:

field initializer is not constant

in-class initialization of static data member of non-literal type

non-constant in-class initiualization invalid for static member

(an out of class initialization is required)

cannot be initialized by a non-constant expression when being decalred

And, of course, it works when I move the initializer out of class but... why exactly? And is there a way to go around it? Should I go around it? What's the most proper way of having this value handy?

Community
  • 1
  • 1
smsware
  • 429
  • 1
  • 13
  • 41
  • 2
    Surely you could take out the lengthiness and shorten your example to make it easier to read? You didn't need to use your _actual_ types and variable names. – Lightness Races in Orbit Jul 28 '14 at 09:41
  • So it sounds like you're asking how to initialise a static data member of type `const QMap, qint32>>`. Right? – Lightness Races in Orbit Jul 28 '14 at 09:42
  • @LightnessRacesinOrbit that would be the question, yes. But I'm not even sure if I need the answer... so my question is more general: "is declaring static data member better than declaring static property and why and if it is better - how to do so?". ;-) – smsware Jul 28 '14 at 09:47
  • That's too broad, too vague, and too goalless. It also has no answer; neither is "better" than the other. What does "better" even mean? – Lightness Races in Orbit Jul 28 '14 at 09:48
  • @LightnessRacesinOrbit I figured that if one would be better - there would be no other. But what is the difference is use of both - that can be answered. – smsware Jul 28 '14 at 09:49
  • @LightnessRacesinOrbit the question will stay unanswered then. Explaining why it can't be answered would be an answer though: e.g. "there is no difference, it's only about different way of calling your data, there is no difference in terms of efficiency; but if you prefer your data to be static data member over static property - here is how you would do it: ..." - that would be acceptable answer. For example... – smsware Jul 28 '14 at 09:54
  • What is a "static property"? That doesn't make mush sense in C++. This is one of the reasons the question is hard to answer. – juanchopanza Jul 28 '14 at 10:09
  • @juanchopanza this function-based way of getting to the data I called "static property" as it looks similar to what's called "static property" in C#. I'm not fighting over terminology here, that's why I gave examples; I don't know how it suppouse to be named or if it is interpreted by C++ in a similar way... that's why I'm asking. – smsware Jul 28 '14 at 10:13

1 Answers1

1

A static const data member of non-literal type must have an out-of-class definition to satisfy the one definition rule: Why can't I initialize non-const static member or static array in class?

When you access a static const data member of non-literal type the member binds to a const reference or to an implicit const this parameter, so it must have a single memory location; this is satisfied by having an out-of-class definition as otherwise there would be no single definition to provide its memory location.

Having a static member function that returns the object will likely be inefficient as the object must be created anew each time the static member function is called.

Community
  • 1
  • 1
ecatmur
  • 152,476
  • 27
  • 293
  • 366