Topic: Should compiler generate template instantiation?
Author: Jason Elbaum <jelbaum@yahoo.com>
Date: Wed, 7 Nov 2001 18:28:20 GMT Raw View
I'm trying to clarify whether a compiler error I'm
seeing is correct according to the standard or not.
Basically, the question is whether the compiler should
be generating a template instantiation or not.
Here's the stripped-down code (it won't run, but what
interests me here is the compilation error, which is
the same as the one in the production code):
template< int W >
class wrapped_int {
public:
wrapped_int(): num(W) { }
operator int() const { return num; }
private:
int num;
};
class int_reader {
public:
int_reader() { }
// This won't link due to the undefined function
const wrapped_int<16>& read() const;
};
int main() {
int_reader in;
const wrapped_int<16>& test = in.read(); // (1)
// const wrapped_int<16> test = in.read(); // (2)
// const wrapped_int<16> dummy; // (3)
int a = test; // (4)
// int a = test.operator int(); // (5)
}
In the code as above, g++ version 2.95.2 reports at
line (4):
`const class wrapped_int<16>' used where a `int' was
expected
Clearly, the compiler isn't instantiating
wrapped_int<16>, since if it did it would generate the
operator int() conversion function.
Replacing line (1) with line (2) makes this work,
since there is an explicit instantiation of
wrapped_int<16> (rather than a reference to it).
Similarly, adding line (3) makes it work. Finally,
replacing line (4) with line (5) works, since the
conversion function is invoked explicitly.
But as the code is written, the compiler, faced with
an assignment from a const wrapped_int<16>& to an int,
fails to generate the necessary instantiation of
wrapped_int<16> to invoke the conversion function.
Now, about the standard (this is my first foray into
standard-mongering, so I hope I'm reading it right):
Section 14.7.1 paragraph 4 reads, "A class template
specialization is implicitly instantiated... if the
completeness of the class type affects the semantics
of the program; in particular, if an expression whose
type is a class template specialization is involved in
overload resolution, pointer conversion, pointer to
member conversion, the class template specialization
is implicitly instantiated...."
An example is given in which D<T> derives from B<T>;
then the following code is correct:
void g(D<char>* pp) {
B<char>* q = pp;
}
since D<char> is instantiated to allow the pointer
conversion.
My code differs in that the line "int a = test" is not
a pointer conversion, but an assignment which depends
on a user-defined conversion function.
The standard seems ambiguous to me. First, it says the
template specialization is instantiated if it "affects
the semantics of the program" - which would appear to
be the case here. But then it specifies cases of
"overload resolution, pointer conversion, pointer to
member conversion" - which doesn't include other forms
of type conversion.
For the record, g++ version 2.91.66 accepts this code,
as do, I'm told, VC++ 6.0 and Solaris SC 6.1.
Can anyone say what the standard requires?
Thanks,
Jason Elbaum
jelbaum@yahoo.com
__________________________________________________
Do You Yahoo!?
Find a job, post your resume.
http://careers.yahoo.com
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Author: Michiel Salters<Michiel.Salters@cmg.nl>
Date: Fri, 9 Nov 2001 10:16:28 CST Raw View
In article <20011107152543.24108.qmail@web9608.mail.yahoo.com>, Jason Elbaum
says...
>
>I'm trying to clarify whether a compiler error I'm
>seeing is correct according to the standard or not.
>Basically, the question is whether the compiler should
>be generating a template instantiation or not.
>Here's the stripped-down code (it won't run, but what
>interests me here is the compilation error, which is
>the same as the one in the production code):
>
>template< int W >
>class wrapped_int {
>public:
> wrapped_int(): num(W) { }
> operator int() const { return num; }
>
>private:
> int num;
>};
>
>
>class int_reader {
>public:
> int_reader() { }
>
> // This won't link due to the undefined function
> const wrapped_int<16>& read() const;
>};
>
>int main() {
> int_reader in;
>
> const wrapped_int<16>& test = in.read(); // (1)
>
>// const wrapped_int<16> test = in.read(); // (2)
>// const wrapped_int<16> dummy; // (3)
>
> int a = test; // (4)
>
>// int a = test.operator int(); // (5)
>}
>
>In the code as above, g++ version 2.95.2 reports at
>line (4):
>
>`const class wrapped_int<16>' used where a `int' was
>expected
>
>Clearly, the compiler isn't instantiating
>wrapped_int<16>, since if it did it would generate the
>operator int() conversion function.
>Now, about the standard (this is my first foray into
>standard-mongering, so I hope I'm reading it right):
>
>Section 14.7.1 paragraph 4 reads, "A class template
>specialization is implicitly instantiated... if the
>completeness of the class type affects the semantics
>of the program; in particular, if an expression whose
>type is a class template specialization is involved in
>overload resolution, pointer conversion, pointer to
>member conversion, the class template specialization
>is implicitly instantiated...."
And your first attempt runs directly into Core issue 212,
where we discovered that this prose indeed is unclear.
Your example shows one reason why; I'm not sure there is
consensus whether this should compile.
Note that members of a class template aren't instantiated
unless absolutely needed. This is useful since some unused
members might actually fail to instantiate for a given
template argument (e.g. not all members of std::vector<T>
can be instantiated if T::T() isn't available).
This seems to be an argument here.
Regards,
Michiel Salters
--
Michiel Salters
Consultant Technical Software Engineering
CMG Trade, Transport & Industry
Michiel.Salters@cmg.nl
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]