0

I've checked posts here that I can use template for nested struct. But when I'm trying to initialize an array inside a nested struct, there seems problem during initialization. In the following example, the array size is one of the parameters of the nested struct so Visual Studio complained that the array size is illegal. Here is the definition:

//template<typename U, typename T>
template<typename U, size_t T>   // this line also not work
struct A {
    struct B {
        struct C {
            vector<U> count[T];    // count needs to have variable size 
            C() {        
                count = new U[T];  // allocate size. Not work
            }
        C c;
    };
    B b;
};

Did I do anything wrong when using the template and initialize the array?

Thanks

15
  • 1
    You are declaring count as an array, then trying to initialize it with a pointer. This is not valid. you can reproduce this by doing int x[5]; x = new int[5]; and get the same error. What exactly are you trying to do? Should the array size be fixed? Or dynamic? Commented May 16, 2022 at 17:23
  • For the moment, get rid of the nesting. Figure out how to get that declaration to work in a less complicated context. Hint: count[T] attempts to use the name of a type T as the size of an array. Commented May 16, 2022 at 17:23
  • oh, i see. array size should be dynamic, related to the T variable Commented May 16, 2022 at 17:24
  • I suggest you invest in some good C++ books. Commented May 16, 2022 at 17:27
  • 1
    vector<U> count[T] is a C-style array of (vectors of Us) with size T. I'm pretty sure you should have std::array<U, T> there and then you don't need a constructor. Commented May 16, 2022 at 17:50

2 Answers 2

1

There are 3 problems with your current code.

Problem 1

You're missing the closing braces and semicolon }; corresponding to the struct A. To solve this just add }; corresponding to struct A as shown below.

Problem 2

T is a template type parameter and hence cannot be used to specify the size of an array. The simplest way of solving this is make T as template nontype parameter as shown below.

Problem 3

count is an array of vectors in your example so count = new U[T]; doesn't make sense. Looking at your comment, you were trying to create count as a vector with elements of type U and size T which can be done as shown below.

Additionally, note that we can't have C c; inside class type C and similarly we can't have B b; inside B. This is because we cannot have a non-static data member of incomplete type inside a class.


Solution

//-------------------vvvvvvvvvvv---->nontype parameter
template<typename U, std::size_t T>
struct A {
    struct B {
        struct C {
            std::vector<U> count; //count is a std::vector    
            C(): count(T) {        
                  std::cout<<"size of count vector is: "<<count.size()<<std::endl;
            }
        //C c;//this won't work here as C is INCOMPLETE at this point
        };//--------->C is complete after this point 
        
        C c; //THIS WORKS HERE because C is COMPLETE at this point
       // B b;//this wont work here as B is INCOMPLETE at this point
    };//------------->B is complete after this point

    B b; //THIS WORKS HERE because B is INCOMPLETE at this point 
};//added this  

Working demo

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

4 Comments

This will not work with the definition of count, with count = new U[T]
@Anoop why need to take out "C c" and "B b" lines? Your solution seems same as Ted's.
@visitor99999 See in my updated/edited answer at which point we can have C c; and B b;. In particular, we can have C c; after C is complete similarly we can have B b; after B is complete. I have written some comments in my answer so that you can see at what point C and B become complete and after that we can use C c; and B b; as i have done in my updated answer. That is, you can use C c; after the }; of struct C and similarly you can use B b; after its corresponding };.
@AnoopRana I see. Now I see I actually misplaced the ";" in my original post. Yes, B and C were incomplete because of the ";". Both yours and Ted's solution would work. I will just upvote both of them, if it's allowed. Thanks.
0

Did I do anything wrong when using the template and initialize the array?

Yes, you do count = new U[T];, but count is not a pointer.

If you want the vector to be initialized to have the size T, provide T to the vector's constructor in the member initializer list:

template<typename U, size_t T>
struct A {
    struct B {
        struct C {
            std::vector<U> count;
            C() : count(T) {}  // now `count´ is constructed with `T` elements
        };                     // <- you are also missing this line
        C c;
    };
    B b;
};

If you really want a fixed size array of T vector<U>s:

#include <array>
template<typename U, size_t T>
struct A {
    struct B {
        struct C {
            std::array<std::vector<U>, T> count;
        };
        C c;
    };
    B b;
};

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.