Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does compiler need complete type when reference is used?

Tags:

c++

class

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?

like image 563
klm123 Avatar asked Oct 21 '25 04:10

klm123


2 Answers

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;
};
like image 142
Bill Lynch Avatar answered Oct 22 '25 17:10

Bill Lynch


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.

like image 30
klm123 Avatar answered Oct 22 '25 19:10

klm123