Incomplete types and templates

D

dave_dp

Hi folks,

I'm interested as to what extent using incomplete types doesn't result
in a undefined behavior, more generally it touches the usage of
incomplete types.. for example, it is stated that you can't use
incomplete types to create objects of type T(that is incomplete), you
can't use pointer arithmetic on T* types, you can't use new T..,...,
you can't use sizeof... but you are allowed to have pointers and
references to T... This is all good so far, but consider this example:

template <typename T>
class BaseClass {
public:
size_t sizeOfArgument() { return sizeof(T); }
};

class Dummy : public BaseClass<Dummy> {
};


int main() {
Dummy dummy;
size_t dummySize = dummy.sizeOfArgument();
}

Now when deriving from BaseClass we pass incomplete type(Dummy) as a
template argument, and in main we call member method that uses sizeof
on incomplete type, does this code result in a undefined behavior? and
is that any different from:

template <typename T>
class Dummy : public BaseClass<Dummy<T> > {
};

int main() {
Dummy dummy<char>;
size_t dummySize = dummy.sizeOfArgument();
}

If it is legal then why? The only argument I can think of right now is
that in main when we instantiate sizeOfArgument member method(member
function isn't instantiated unless it's used) Dummy is complete type...
I'm lost anyways..


TIA.
 
K

kwikius

If it is legal then why? The only argument I can think of right now is
that in main when we instantiate sizeOfArgument member method(member
function isn't instantiated unless it's used) Dummy is complete type...
I'm lost anyways..

I can't answer your questions exactly but look up CRTP which stands for
Curiously Recurring Template Pattern. Its all to do with the fact that
templates are instantiated only when required AFAIK.

Also you can do this with CRTP as an alternative to virtual functions
--->

Not sure if it helps but its quite cool anyway!

regards
Andy Little

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

#include <iostream>

template <typename T>
class BaseClass {
public:
size_t sizeOfArgument() { return sizeof(T); }

void f()
{
T * t = static_cast<T*>(this);
t->derived_f();
}
};


class Dummy : public BaseClass<Dummy> {
public:
void derived_f()
{
std::cout << "Hello from Dummy\n";
}
};

class Wummy : public BaseClass<Wummy> {
public:
void derived_f()
{
std::cout << "Hello from Wummy\n";
}
};

int main() {

Dummy dummy;
size_t dummySize = dummy.sizeOfArgument();
dummy.f();
Wummy wummy;
wummy.f();
}

/*
output:

Hello from Dummy
Hello from Wummy

*/
 
D

dave_dp

kwikius said:
I can't answer your questions exactly but look up CRTP which stands for
Curiously Recurring Template Pattern. Its all to do with the fact that
templates are instantiated only when required AFAIK.

Also you can do this with CRTP as an alternative to virtual functions
--->

Not sure if it helps but its quite cool anyway!

regards
Andy Little

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

#include <iostream>

template <typename T>
class BaseClass {
public:
size_t sizeOfArgument() { return sizeof(T); }

void f()
{
T * t = static_cast<T*>(this);
t->derived_f();
}
};


class Dummy : public BaseClass<Dummy> {
public:
void derived_f()
{
std::cout << "Hello from Dummy\n";
}
};

class Wummy : public BaseClass<Wummy> {
public:
void derived_f()
{
std::cout << "Hello from Wummy\n";
}
};

int main() {

Dummy dummy;
size_t dummySize = dummy.sizeOfArgument();
dummy.f();
Wummy wummy;
wummy.f();
}

/*
output:

Hello from Dummy
Hello from Wummy

*/
Hi,

Yes, I happen to read-up on CRTP but I didn't mention its name because
I'm concerned generally about incomplete types and their usage, that
doesn't only include CRTP(hence my example) but I can also reproduce
same type of thing without touching CRTP. for example:

template <typename T>
class BaseClass {
public:
size_t sizeOfArgument() { return sizeof(T); }



};

class SomeClass;
BaseClass<SomeClass> someGlobal;

class SomeClass { };

int main() {
size_t sizeOfSmth = someGlobal.sizeOfArgument();

}

So to get back to my original question, am I right in assumption that
at the point of instantiation of template member method sizeOfArgument,
type is complete that's why it isn't UB? So if I'll make SomeClass
definition out of main's reach it would be therefore an UB?

TIA.
 

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,755
Messages
2,569,536
Members
45,011
Latest member
AjaUqq1950

Latest Threads

Top