473,395 Members | 1,738 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,395 software developers and data experts.

Incomplete type as template argument

Hi All,

Considering the following code:

struct A;

struct B
{
std::list<A> l;
};

void foo()
{
B b;
};

struct A
{
int x;
};

int main()
{
foo();
A a;
a.x = 22;
B b;
b.l.push_back(a);
cout << "A's value = " << b.l.begin()->x << endl;
}

I do not understand why the compiler does not complain when encountered with std::list<A>
when A has not been fully defined.
Could someone please explain to me when the compiler actually does the template expansion,
and is this method of using incomplete types as template arguments safe for all compliant
compilers?

Andy
Jul 22 '05 #1
7 4917
"Andrew Ward" <an***@ihug.co.nz> wrote...
Hi All,

Considering the following code:

struct A;

struct B
{
std::list<A> l;
Neither 'std' nor 'list' is defined.
};

void foo()
{
B b;
};

struct A
{
int x;
};

int main()
{
foo();
A a;
a.x = 22;
B b;
b.l.push_back(a);
cout << "A's value = " << b.l.begin()->x << endl;
}

I do not understand why the compiler does not complain when encountered with std::list<A> when A has not been fully defined.
I do not understand either. Comeau C++ does complain.
Could someone please explain to me when the compiler actually does the template expansion, and is this method of using incomplete types as template arguments safe for all compliant compilers?


You should probably ask whoever made your compiler. They must hold
the secret of how to use an incomplete type as a template argument...

Victor
Jul 22 '05 #2

"Andrew Ward" <an***@ihug.co.nz> wrote in message
news:hV*****************@news.xtra.co.nz...
Hi All,

Considering the following code:

struct A;

struct B
{
std::list<A> l;
};

void foo()
{
B b;
};

struct A
{
int x;
};

int main()
{
foo();
A a;
a.x = 22;
B b;
b.l.push_back(a);
cout << "A's value = " << b.l.begin()->x << endl;
}


Which compiler?
Atleast VC 7, g++ 3.3.1 and Comeau online reject this code.

-Sharad
Jul 22 '05 #3
"Andrew Ward" <an***@ihug.co.nz> wrote in message
news:hV*****************@news.xtra.co.nz...
Hi All,

Considering the following code:

<snip>

I do not understand why the compiler does not complain when encountered with std::list<A> when A has not been fully defined.
Could someone please explain to me when the compiler actually does the template expansion, and is this method of using incomplete types as template arguments safe for all compliant compilers?


This topic has been extensively discussed on comp.lang.c++.moderated
recently. (See "class definition containing member of own type",
etc. )

According to the language rules, it may well be possible to
instantiate std::list with an incomplete type (depending on the
implementation.) However, the library requirements specifically make
it undefined behaviour to instantiate a standard library template with
an incomplete type (17.4.3.6).

Presumably this will change, since one of the benefits of shared_ptr
is supposed to be that it can be instantiated with an incomplete type.
(I don't see anything about this in the TR1 draft, though.)

Jonathan
Jul 22 '05 #4
"Sharad Kala" <no*****************@yahoo.com> wrote in message
news:c1*************@ID-221354.news.uni-berlin.de
"Andrew Ward" <an***@ihug.co.nz> wrote in message
news:hV*****************@news.xtra.co.nz...
Hi All,

Considering the following code:

struct A;

struct B
{
std::list<A> l;
};

void foo()
{
B b;
};

struct A
{
int x;
};

int main()
{
foo();
A a;
a.x = 22;
B b;
b.l.push_back(a);
cout << "A's value = " << b.l.begin()->x << endl;
}


Which compiler?
Atleast VC 7, g++ 3.3.1 and Comeau online reject this code.

-Sharad

VC++ 7.1 accepts it.
--
John Carson
1. To reply to email address, remove donald
2. Don't reply to email address (post here instead)
Jul 22 '05 #5
"Victor Bazarov" <v.********@comAcast.net> wrote in message
news:g5W_b.54098$Xp.257962@attbi_s54
"Andrew Ward" <an***@ihug.co.nz> wrote...
Hi All,

Considering the following code:

struct A;

struct B
{
std::list<A> l;


Neither 'std' nor 'list' is defined.
};

void foo()
{
B b;
};

struct A
{
int x;
};

int main()
{
foo();
A a;
a.x = 22;
B b;
b.l.push_back(a);
cout << "A's value = " << b.l.begin()->x << endl;
}

I do not understand why the compiler does not complain when
encountered with std::list<A> when A has not been fully defined.


I do not understand either. Comeau C++ does complain.
Could someone please explain to me when the compiler actually does
the template expansion, and is this method of using incomplete types
as template arguments safe for all compliant compilers?


You should probably ask whoever made your compiler. They must hold
the secret of how to use an incomplete type as a template argument...

Victor

I don't claim to understand all the subtleties of this matter but... section
14.3.1 p2 of the 2003 standard says:

"[Note: a template type argument may be an incomplete type (3.9). ]"
--
John Carson
1. To reply to email address, remove donald
2. Don't reply to email address (post here instead)

Jul 22 '05 #6

"Sharad Kala" <no*****************@yahoo.com> wrote in message
news:c1*************@ID-221354.news.uni-berlin.de...

"Andrew Ward" <an***@ihug.co.nz> wrote in message
news:hV*****************@news.xtra.co.nz...
Hi All,

Considering the following code:

struct A;

struct B
{
std::list<A> l;
};

void foo()
{
B b;
};

struct A
{
int x;
};

int main()
{
foo();
A a;
a.x = 22;
B b;
b.l.push_back(a);
cout << "A's value = " << b.l.begin()->x << endl;
}


Which compiler?
Atleast VC 7, g++ 3.3.1 and Comeau online reject this code.

-Sharad


I am using VC 7.1, I am guessing from the responses though that this kind of code is not a
good idea for compatibility with other compilers. The reason I wanted to do this was
because I am trying to reduce the number of #includes in my header files, as to speed up
compiles when changes are made to the headers.

Jul 22 '05 #7
On Wed, 25 Feb 2004 17:55:12 +1300, "Andrew Ward" <an***@ihug.co.nz>
wrote:
Hi All,

Considering the following code:
[SNIP list<incomplete> example]
I do not understand why the compiler does not complain when encountered with std::list<A>
when A has not been fully defined.
Could someone please explain to me when the compiler actually does the template expansion,
and is this method of using incomplete types as template arguments safe for all compliant
compilers?


In general it is undefined behaviour to instantiate any standard
container type with an incomplete type parameter. However, it has also
been shown that an implementation of the standard library can
carefully be written so that it will work with an incomplete type -
the main things to do are to no have any nested types, e.g. make
vector::iterator a typedef for a non-nested type.

To understand why, you need to know a little bit about implicit
instantiation. A class template specialization isn't instantiated
until it is used in a context that requires a completely defined
object type. So:

typedef mytemplate<int> t; //no instantiation
mytemplate<int> t; //no instantiation
sizeof(mytemplate<int>); //instantiation
mytemplate<int> t; //instantiation, possibly also of default
constructor

Now, when a class template definition is instantiated, any types that
need to be complete in the class definition are also instantiated.
e.g.

template <class T>
struct Foo
{
Bar<T> bar; //member, so instantiated
Baz<T>* baz; //pointer, so not instantiated
class Inner //member, so instantated
{
char array[sizeof(Baz<T>)]; //Baz<T> instantiated
};
};
So once you understand those rules, consider how std::list might be
implemented (ignoring the allocator parameter)

template <class T>
class list
{
struct Node
{
//boom, requires T to be complete
//when list<T> is instantiated
T value;
Node* prior;
Node* next;
};
//...
};

If you take the node type out, then you have:

template <class T>
struct ListNode
{
T value;
ListNode* prior;
ListNode* next;
};

template <class T>
class list
{
//doesn't instantiate ListNode<T> when list<T> is instaniated
typedef ListNode<T> node_t;
//doesn't instantiate ListNode<T>
node_t* node;
//... etc
};

GCC allows use of all containers with incomplete types. Dinkumware
have finally updated their library to do the same, and VC7.1 benefits.
Many other compilers (including earlier versions of MSVC) don't allow
incomplete types. Perhaps a future standard will guarantee that
containers can be instantiated with incomplete types, but don't hold
your breath.

Tom
--
C++ FAQ: http://www.parashift.com/c++-faq-lite/
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
Jul 22 '05 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: Mikhail N. Kupchik | last post by:
Hi All. I have a question regarding C++ programming language standard. It is related to standard library, not to the core language. Is it portable to instantiate template class std::list<>...
2
by: Anthony Borla | last post by:
Greetings, I hope everyone is enjoying the Holiday Season :) ! I'm attempting to implement a function template modelled somewhat on the STL's, 'generate' and 'generate_n' algorithms. Now,...
1
by: Alan Johnson | last post by:
From the standard 5.3.5/5: "If the object being deleted has incomplete class type at the point of deletion and the complete class has a non-trivial destructor or a deallocation function, the...
13
by: imutate | last post by:
Hi, I am migrating some std::vectors to use a template instead, but I get an incomplete type error in a struct declaration. #include <vector> template < typename T > class Vec : public...
2
by: dave_dp | last post by:
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...
2
by: Alan | last post by:
I get a compilation error "parameter 2 of `Clusters sorted(Clusters, func_obj)' has incomplete type `func_obj' " when attempting to compile the following code: some_clusters =...
2
by: Kai-Uwe Bux | last post by:
Does the following have undefined behavior? struct X; struct Y { X * x_ptr; Y ( void ) : x_ptr ( 0 )
5
by: Belebele | last post by:
The code below does not compile under g++. There is an outer class template that contains and inner class template. The outer class template is fully specialized for int. Then a separate Foo...
50
by: Juha Nieminen | last post by:
I asked a long time ago in this group how to make a smart pointer which works with incomplete types. I got this answer (only relevant parts included): ...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.