2

I am wondering whether one can create a structure and, using the members/variables initialized in the structure as parameters, build other members. For example, I would like to make a structure:

struct myStruct {
    size_t length;
    std::string (&strings)[length]; // from the above variable
};

Something like this. And I understand that there are some subtleties regarding initialization order, but I'm sure that something could be worked out (constructors maybe?) to overcome that problem. Currently, the only way I've found that works is templates:

template <size_t N>
struct myStruct {
    int length;
    std::string (&strings)[N]; // from the template parameter
};

Keep in mind that I actually pass my length value as a member variable in the struct, so ideally I won't need a template.

Edit:
Clarification: I need only to access the string of arrays and be able to read from them (no need to overwrite them, so const could and should be used) as one would do with a regular array: []-based notation. I could also tolerate a change to std::array. Anyways, I just need the strings easily accessible in a way not starkly different from regular usage. Also, it must be from a struct pointer (a.k.a. arrow operator).

Thanks much!

Jonathan Lee
  • 153
  • 8
  • 3
    Unfortunately you have picked a bad example for your question. In general the answer to your question is yes but in your specific example it is no as the length of a array must be a compile time constant. Also, I'm not sure what you expect `std::string (&strings)[N]` to be but if it is an array of references then that is also illegal. – NathanOliver Aug 15 '18 at 21:00
  • @NathanOliver Array of strings? I need to be able to use that specific struct member through a pointer like `((struct myStruct *) structptr->strings)[15]` or something similar. I'm not too familiar. – Jonathan Lee Aug 15 '18 at 21:04
  • 1
    If you want to have array of strings, you should use `std::array` - note there is no references here. – SergeyA Aug 15 '18 at 21:05
  • Oh, you want a reference to an array of strings, got it. I was thinking you were trying to make an array of references to strings. – NathanOliver Aug 15 '18 at 21:06
  • And, if you want a reference to array of strings, keep in mind that having a reference as a class member, while allowed, is not necessarily the greatest idea. You might be better of with a (non-owning) pointer – SergeyA Aug 15 '18 at 21:07
  • @SergeyA Well, I just put the reference there because I mean that's how people usually grab a string (not a copy, as used with something like `std::string strings[N]`). I personally don't need to change anything in it, so I could even do a `const` keyword; I just need to be able to read from it like regular arrays from a pointer to the structure. – Jonathan Lee Aug 15 '18 at 21:15

1 Answers1

5

You may not use

struct myStruct {
    size_t length;
    std::string (&strings)[length];
};

since length is not a compile time constant.

Your best option is probably to use std::vector<std::string>&.

struct myStruct {
    // Assuming you were using a reference on purpose.
    std::vector<std::string>& strings;
};

and initialize it in the constructor.

struct myStruct {
    myStruct(std::vector<std::string>& in) : strings(in) {}
    std::vector<std::string>& strings;
};

If the size of the array is known at compile time, there are couple of choices.

  1. Use a regular array of std::strings.

    template <size_t N>
    struct myStruct {
        int length;
        std::string (&strings)[N];
    };
    
  2. Use a std::array of std::strings.

    template <size_t N>
    struct myStruct {
        int length;
        std::array<std::string, N>& strings;
    };
    

The second option is better since std::arrays have everything that a regular array has plus more.

R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • Yeah, I figured. Are templates the best way? – Jonathan Lee Aug 15 '18 at 21:00
  • Assuming you wanted the reference to an array of strings, a size template parameter is the only way. – Karl Aug 15 '18 at 21:08
  • 1
    @JonathanLee, I don't know what would work best for your needs, an array (whose size must be known at compile time) or a `std::vector` (whose size is can be decided at run time). If an array, then yes, using a template is the best way. – R Sahu Aug 15 '18 at 21:15
  • I think `std::array` might be the way to go. I just ran a test program and it works fine. I'll accept your answer if you add that small footnote. – Jonathan Lee Aug 15 '18 at 21:24
  • @JonathanLee, you got it. – R Sahu Aug 15 '18 at 21:35