If I have a header like this:
#include <vector>
class Data;
class A {
// const Data& getData( int i ) const { return a[i]; }
std::vector<Data> a;
};
the compiler compiles it normally, because it doesn't need to know a bit about Data type.
Retuning a value by reference does not depend on a class implementation and therefore do not require any knowledge of the class internals.
But when I uncomment the accessor compiler starts to complain on invalid use of incomplete type 'class Data'. Why?
So, the C++ Standard is not particularly clear on this point. The problem that you are hitting is whether or not you can instantiate vector<Data> when you Data is not a complete type.
If we look at Section 17.6.4.8 Paragraph 2, we find the following statement:
In particular, the effects are undefined in the following cases:
- ...
- if an incomplete type (3.9) is used as a template argument when instantiating a template component, unless specifically allowed for that component.
std::vector does not explicitly allow incomplete types for the template argument, so this is technically invalid code.
This would mean that this is invalid code, even if your compiler accepts it.
class Data;
class A {
std::vector<Data> a;
};
Thanks to people reaction I understood the problem better.
It becomes more clear when we rid from std::vector:
class Data;
class A {
const Data& getData( int i ) const { return a[i]; }
Data* a;
};
to return i-th element of array a one needs to know where is it in the memory. For this one needs to know sizeof(Data), which is not possible for incomplete type.
The exactly same problem std::vector should have.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With