By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
454,127 Members | 939 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 454,127 IT Pros & Developers. It's quick & easy.

Incomplete types and templates

P: n/a
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
Share this Question
Share on Google+
2 Replies


P: n/a

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

P: n/a

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.