Alf P. Steinbach wrote:
* Paul Bibbings, on 16.06.2010 11:28:
"Alf P. Steinbach"<alfps@start.no> writes:
* Bart van Ingen Schenau, on 16.06.2010 10:31:
On Jun 15, 6:11 pm, Chen Zhuhui<eksche...@gmail.com> wrote:
Dear All,
I'm reading appendix C.13.8.3 in TC++PL special ed. and it says:
"
The definition of "instantiation point" implies that a template
parameter can never be bound to a local name or a class member. For
example:
void f()
{
struct X { /* ... */ }; // local structure
vector<X> v; // error: cannot use local structure as
// template parameter
// ...
}
.......
"
<snip>
So if I haven't misunderstood something, the example is showing
about "a
template parameter can never be bound to a local name". But how
about "a
class member"? I cannot figure myself out an example of this
situation. I've tried:
struct classA
{
struct classB { };
typedef int classC;
void classAF()
{
vector<classB> v1; // 1
vector<classC> v2; // 2
}
};
Try this one:
struct class A
{
struct classB { };
typedef int class C;
vector<classB> v1; // 5
vector<classC> v2; // 6
};
I tried the following code with Comeau Online:
<code>
#include<vector>
using namespace std;
struct classA
{
struct classB { };
typedef int classC;
vector<classB> v1; // 5
vector<classC> v2; // 6
};
int main()
{ classA(); }
</code>
It compiled with no errors or warnings.
From the given out-of-context quote it's very unclear what Bjarne is
talking about.
Since Appendix C is the one that is not publicly available, and some
of us (like me) do not have the 3rd edition of that book, perhaps the
OP could clarify -
Here is the text of the relevant section, up to the point just before
the OP's original quote. Effective it gives the `definition' of point
of instantiation that is used in the quote presented by the OP.
C.13.8.3 Point of Instantiation Binding
"Each use of a template for a given set of template arguments defines
a point of instantiation. That point is the nearest global or
namespace scope enclosing its use, just before the declaration that
contains that use. For example:
template<class T> void f(T a) { g(a); }
void g(int);
void h()
{
extern g(double);
f(2);
}
Here, the point of instantiation for f<int>() is just before h(), so
that the g() called in f() is the global g(int) rather than the local
g(double)."
Oh, that's pre-standard semantics. From which one can tentatively deduce
that the OP, and you, are reading an edition of TCP++L published before
1998. With the 1998 standardization the rules changed to "two phase"
lookup, and the above pre-standard code will not compile; the relevant
section of the C++98 standard is ?14.6/9
"If a name does not depend on a template parameter (as defined in
14.6.2),
a declaration (or a set of declarations) for that name shall be in
scope
at the point where the name appears in the template definition; the
name
is bound to the declaration (or declarations) found at that point
and this
binding is not affected by declarations that are visible at the
point of
instantiation."
So with the 1998 rules the above code shall not compile without a
diagnostic since g does not depend on a template parameter and is not in
scope at the point where the name appears in the template definition.
<code>
template<class T> void f(T a) { g(a); }
void g(int);
void h()
{
extern g(double);
f(2);
}
int main() { h(); }
</code>
<compilation result>
Comeau C/C++ 4.3.10.1 (Oct 6 2008 11:28:09) for ONLINE_EVALUATION_BETA2
Copyright 1988-2008 Comeau Computing. All rights reserved.
MODE:strict errors C++ C++0x_extensions
"ComeauTest.c", line 7: error: explicit type is missing ("int" assumed)
extern g(double);
^
"ComeauTest.c", line 1: error: identifier "g" is undefined
template<class T> void f(T a) { g(a); }
^
detected during instantiation of "void f(T) [with T=int]" at
line 8
2 errors detected in the compilation of "ComeauTest.c".
</compilation result>
No wonder that Bjarne's comment didn't seem to make sense: he was
discussing pre-standard rules!
taken from the Special Edition (2nd Printing, March 2000). What is
scope(?4.9.4) at the point of definition. For example: