CRTP - incomplete type .... used in nested name specifier

F

Frank Bergemann

Hi,

i have a problem with applying CRTP.
Here is a short example, which demonstrate it:

========= base.h ==========
template <typename TYPE>
class Base
{
public:
Base()
{ /* void */ }

virtual ~Base()
{ /* void */ }

char buff[TYPE::MAX - TYPE::MIN + 1];
};

========== test.cc ==========
#include "base.h"


class Sample : public Base<Sample>
{
public:
Sample()
: Base<Sample>()
{ /* void */ }

~Sample()
{ /* void */ }

typedef enum {
MIN = 0,
MAX = 10
} Internal_t;
};

int main(int, char**)
{
return 0;
}

-----------------------------------------------

Compilation raises an error:

frank@charlie:~/TEST$ /usr/bin/g++ -o test test.cc
base.h: In instantiation of 'Base<Sample>':
test.cc:5: instantiated from here
base.h:13: error: incomplete type 'Sample' used in nested name
specifier
base.h:13: error: incomplete type 'Sample' used in nested name
specifier
base.h:13: error: array bound is not an integer constant

I could do a workaround and switch to std::vector<char> and allocate
in c'tor via some Sample::getSize().
But i wonder, if there is really no way to use the enum values in the
template base class?
(and if so: why?)

- many thanks!

rgds,
Frank
 
B

Bo Persson

Frank said:
Hi,

i have a problem with applying CRTP.
Here is a short example, which demonstrate it:

========= base.h ==========
template <typename TYPE>
class Base
{
public:
Base()
{ /* void */ }

virtual ~Base()
{ /* void */ }

char buff[TYPE::MAX - TYPE::MIN + 1];
};

========== test.cc ==========
#include "base.h"


class Sample : public Base<Sample>
{
public:
Sample() : Base<Sample>()
{ /* void */ }

~Sample()
{ /* void */ }

typedef enum {
MIN = 0,
MAX = 10
} Internal_t;
};

int main(int, char**)
{
return 0;
}

-----------------------------------------------

Compilation raises an error:

frank@charlie:~/TEST$ /usr/bin/g++ -o test test.cc
base.h: In instantiation of 'Base<Sample>':
test.cc:5: instantiated from here
base.h:13: error: incomplete type 'Sample' used in nested name
specifier
base.h:13: error: incomplete type 'Sample' used in nested name
specifier
base.h:13: error: array bound is not an integer constant

The compiler is correct. At the line

class Sample : public Base<Sample>

the Sample class is not complete, so its content isn't known yet.

Technically you also have the problem that sizeof(Sample) depends on
sizeof(Base), which depends on Sample's enum. That's not going to
work!
I could do a workaround and switch to std::vector<char> and allocate
in c'tor via some Sample::getSize().

Or pass it as a parameter to the Base constructor.


Bo Persson
 
F

Frank Bergemann

Hi Bo,

Bo said:
The compiler is correct. At the line

class Sample : public Base<Sample>

the Sample class is not complete, so its content isn't known yet.

Technically you also have the problem that sizeof(Sample) depends on
sizeof(Base), which depends on Sample's enum. That's not going to
work!


Or pass it as a parameter to the Base constructor.


Bo Persson

- thanks (once again :) for your help, Bo!

"in real" life i had a number of type definitions in Sample,
which i wanted to be handled in my template base class.
E.g. it should manage a container of 'Sample'-typed elements.
Therefore i couldn't use the Base constructor for this.
(it wasn't just some (int) size-information).
So i shifted the necessary stuff to some extra SampleCfg class.
And made my Sample class this way:

class Sample : public Base<SampleCfg, Sample>
{
typedef SampleCfg Cfg;
[...]
};

But another thing i recognized for this:
If i map in some enum type:

class Sample : public Base<SampleCfg, Sample>
{
typedef SampleCfg Cfg;

typedef Cfg::MyEnum_t MyEnum_t;
[...]
};

Then i can't access the MyEnum_t's literals as Sample::FIRST_VAL (e.g.).
But i have to use Sample::Cfg::FIRST_VAL.

Why doesn't the
typedef Cfg::MyEnum_t MyEnum_t;

.... within class Sample also "adopt" the names of MyEnum_t elements into
class Sample?

TIA!

cheers,
Frank
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top