469,909 Members | 1,765 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,909 developers. It's quick & easy.

Incomplete types and templates

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.

--
Regards,
David

Dec 23 '06 #1
2 1786

da*****@mail.ru wrote:
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

*/

Dec 23 '06 #2

kwikius wrote:
da*****@mail.ru wrote:
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

*/
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<SomeClasssomeGlobal;

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.

--
David

Dec 23 '06 #3

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

7 posts views Thread by Andrew Ward | last post: by
4 posts views Thread by Mikhail N. Kupchik | last post: by
1 post views Thread by andrew | last post: by
reply views Thread by Steven T. Hatton | last post: by
5 posts views Thread by Paul F. Dietz | last post: by
6 posts views Thread by Eric Smith | last post: by
7 posts views Thread by Michael Birkmose | last post: by
2 posts views Thread by Kai-Uwe Bux | last post: by
1 post views Thread by Waqarahmed | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.