5

I working with C++11 and have a Class containing the following Struct:

struct Settings{
    const std::string name;

    const std::string* A;
    const size_t a;
};

class X {
    static const Settings s;
    //More stuff
};

In the .cpp file I want to define it like this

X::s = {"MyName", {"one","two","three"}, 3};

But this does not work. However it does work using an intermediate variable

const std::string inter[] = {"one","two","three"};
X::s = {"MyName", inter, 3};

Is there a way to do it without the intermediate variable?

3
  • 3
    Your struct does not contain a const array. It contains a pointer to a const string. With that in mind, it should be easy to see why you need the "intermediate variable". Commented May 21, 2013 at 18:29
  • @juanchopanza: Well, I want A to point to (the beginning of) a const Array. It could also be a pointer to a const std::string, but thats not what I want. But maybe I don't quite get what you are pointing at... Commented May 21, 2013 at 18:32
  • 1
    @Haatschii: you're confusing the fact that an array decays into a pointer with the idea that an array and a pointer are identical. In terms of the language semantics, an array is not a pointer. Likewise, an initializer list is not an array. The compiler can initialize an array with such a list, and it can decay an array into a pointer, but it doesn't know in your example to convert the list into an array and then decay that to a pointer. Hence the need for the intermediary, to get the initializer list converted to a contiguous array before assigning to the pointer. Commented May 21, 2013 at 20:26

2 Answers 2

5

A pointer cannot be initialized from a list of values. You could use std::vector instead:

#include <vector>

struct Settings{
    const std::string name;
    const std::vector<std::string> A;
//        ^^^^^^^^^^^^^^^^^^^^^^^^
    const size_t a;
};

You can then write:

class X {
    static const Settings s;
    //More stuff
};

const Settings X::s = {"MyName", {"one","two","three"}, 3};

Here is a live example.

As suggested by Praetorian in the comments, you may want to replace std::vector with std::array, if it is acceptable for you to specify the size of the container explicitly, and if the size does not need to change at run-time:

#include <array>

struct Settings{
    const std::string name;
    const std::array<std::string, 3> A;
//        ^^^^^^^^^^^^^^^^^^^^^^^^^^
    const size_t a;
};

And here is the live example.

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

8 Comments

Could you explain why using vector makes the difference?
@taocp: Because a pointer cannot be initialized with a list of values. What you want is something that can be initialized from an initializer list
Or std::array<std::string, 3> if you don't need for it to be resizable.
@Praetorian: Indeed, if the user accepts to write the size explicitly
Thanks! I, hoped to get around using a vector but from your explanation I guess there is no way. std::array is no alternative since I can't specify the array size in the definition of the struct. By the way, is there any difference between a const std::vector and a const std::array, except that the size of the array must be given at the definition? (More a new question, but it just came to my mind)
|
5

That's because you're storing a pointer to an array of strings, not the strings themselves; so you need an array of strings somewhere to point to. All you have is a brace-initialiser containing pointers to character arrays.

If you were to store the strings themselves (in a vector<string>, for example), then the first version would work.

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.