 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Niels Dekker - no reply a Guest
|
Posted: Sat Jan 28, 2006 1:15 am Post subject: How to pass this template template argument? (MSVC++ 8 error |
|
|
The following attempt to pass my template "Base" as a template template
argument was rejected by Microsoft VC++ 8.0 (2005), while it still works
on VC++ 7.1 (2003). Is it correct C++? And is there a workaround?
template <typename T> class Base
{
};
template <typename U, template <typename> class TempTemp>
class Derived;
template <typename V>
class Derived<V, Base> : public Base<V>
{
public:
template <typename W> void Fun(Derived<W, Base>&) // <-- error!?!
{
}
};
MSVC++ 8.0 says about Fun(Derived<W, Base>&):
error C3200: 'Base<T>' : invalid template argument for template
parameter 'TempTemp', expected a class template
see reference to class template instantiation 'Derived<V,Base>' being
compiled
Kind regards,
Niels Dekker
www.xs4all.nl/~nd/dekkerware |
|
| Back to top |
|
 |
Victor Bazarov Guest
|
Posted: Sat Jan 28, 2006 1:15 am Post subject: Re: How to pass this template template argument? (MSVC++ 8 e |
|
|
Niels Dekker - no reply address wrote:
| Quote: | The following attempt to pass my template "Base" as a template
template argument was rejected by Microsoft VC++ 8.0 (2005), while it
still works on VC++ 7.1 (2003). Is it correct C++? And is there a
workaround?
template <typename T> class Base
{
};
template <typename U, template <typename> class TempTemp
class Derived;
template <typename V
class Derived<V, Base> : public Base<V
{
public:
template <typename W> void Fun(Derived<W, Base>&) // <-- error!?!
{
}
};
MSVC++ 8.0 says about Fun(Derived<W, Base>&):
error C3200: 'Base<T>' : invalid template argument for template
parameter 'TempTemp', expected a class template
see reference to class template instantiation 'Derived<V,Base>' being
compiled
|
I just added this:
int main()
{
Derived<int,Base> di;
Derived<char,Base> dc;
di.Fun(dc);
}
And compiled it successfully with VC++ v8.0.
Please next time post the _complete_ code if you want us to be able
to help you with any particular problem.
V |
|
| Back to top |
|
 |
John Carson Guest
|
Posted: Sat Jan 28, 2006 1:15 am Post subject: Re: How to pass this template template argument? (MSVC++ 8 e |
|
|
"Victor Bazarov" <v.Abazarov (AT) comAcast (DOT) net> wrote in message
news:EZKdnUgscfkwJUfeRVn-rg (AT) comcast (DOT) com
| Quote: | Niels Dekker - no reply address wrote:
The following attempt to pass my template "Base" as a template
template argument was rejected by Microsoft VC++ 8.0 (2005), while it
still works on VC++ 7.1 (2003). Is it correct C++? And is there a
workaround?
template <typename T> class Base
{
};
template <typename U, template <typename> class TempTemp
class Derived;
template <typename V
class Derived<V, Base> : public Base<V
{
public:
template <typename W> void Fun(Derived<W, Base>&) // <-- error!?!
{
}
};
MSVC++ 8.0 says about Fun(Derived<W, Base>&):
error C3200: 'Base<T>' : invalid template argument for template
parameter 'TempTemp', expected a class template
see reference to class template instantiation 'Derived<V,Base>'
being compiled
I just added this:
int main()
{
Derived<int,Base> di;
Derived<char,Base> dc;
di.Fun(dc);
}
And compiled it successfully with VC++ v8.0.
|
Strange. It won't compile for me on either VC++ Express 2005 or a Release
Candidate of VS Team System.
--
John Carson |
|
| Back to top |
|
 |
John Carson Guest
|
Posted: Sat Jan 28, 2006 1:15 am Post subject: Re: How to pass this template template argument? (MSVC++ 8 e |
|
|
"Niels Dekker - no reply address" <unknown (AT) this (DOT) is.invalid> wrote in
message news:43DAA009.F245D9DF (AT) this (DOT) is.invalid
| Quote: | The following attempt to pass my template "Base" as a template
template argument was rejected by Microsoft VC++ 8.0 (2005), while it
still works on VC++ 7.1 (2003). Is it correct C++? And is there a
workaround?
template <typename T> class Base
{
};
template <typename U, template <typename> class TempTemp
class Derived;
template <typename V
class Derived<V, Base> : public Base<V
{
public:
template <typename W> void Fun(Derived<W, Base>&) // <-- error!?!
{
}
};
|
The workaround is to qualify Base with ::, so that it becomes:
template <typename W> void Fun(Derived<W, ::Base>&)
{
}
As for whether your original code is valid C++, I am inclined to think that
it is but I wouldn't bet my life on it. The strongest indication that the
original code is valid is that Comeau compiles it without complaint.
I believe what is happening is the following. VC++ 8 is reading Base as
Base<V>. In the following simpler example, that would be correct:
template <class V>
class Base
{
Base b; // read this as Base<V>
};
If you wanted to refer to the template Base inside Base, then you could use
::Base.
Where VC++ 8 appears to have gone subtlely wrong is in treating Base in
Derived the same way as it would treat Base in Base. Because Base is a
dependent base (i.e., it depends on V), two phase lookup (as I understand
it) says that it should not be looked up until the template is instantiated.
Thus Base<V> is not seen when Fun is defined, with the result that Base is
treated as a template, so the code compiles. VC++ does not support two phase
lookup, so it does see Base<V> when Fun is defined and hence gives an
error...or at least I think that is the explanation.
--
John Carson |
|
| Back to top |
|
 |
Victor Bazarov Guest
|
Posted: Sat Jan 28, 2006 1:15 am Post subject: Re: How to pass this template template argument? (MSVC++ 8 e |
|
|
John Carson wrote:
| Quote: | "Victor Bazarov" <v.Abazarov (AT) comAcast (DOT) net> wrote in message
news:EZKdnUgscfkwJUfeRVn-rg (AT) comcast (DOT) com
Niels Dekker - no reply address wrote:
The following attempt to pass my template "Base" as a template
template argument was rejected by Microsoft VC++ 8.0 (2005), while
it still works on VC++ 7.1 (2003). Is it correct C++? And is
there a workaround?
template <typename T> class Base
{
};
template <typename U, template <typename> class TempTemp
class Derived;
template <typename V
class Derived<V, Base> : public Base<V
{
public:
template <typename W> void Fun(Derived<W, Base>&) // <-- error!?!
{
}
};
MSVC++ 8.0 says about Fun(Derived<W, Base>&):
error C3200: 'Base<T>' : invalid template argument for template
parameter 'TempTemp', expected a class template
see reference to class template instantiation 'Derived<V,Base>'
being compiled
I just added this:
int main()
{
Derived<int,Base> di;
Derived<char,Base> dc;
di.Fun(dc);
}
And compiled it successfully with VC++ v8.0.
Strange. It won't compile for me on either VC++ Express 2005 or a
Release Candidate of VS Team System.
|
Compiled for me on Express 2005. Are you sure you used the same code?
-------------- this is from your post
template<typename T> class Base
{
};
template<typename U, template<typename> class TempTemp> class Derived;
template<typename V> class Derived<V, Base> : public Base<V>
{
public:
template <typename W> void Fun(Derived<W, Base>&) // <-- error!?!
{
}
};
// -------------- this I added...
int main()
{
Derived<int,Base> di;
Derived<char,Base> dc;
di.Fun(dc);
}
--------------
V
--
Please remove capital As from my address when replying by mail |
|
| Back to top |
|
 |
John Carson Guest
|
Posted: Sat Jan 28, 2006 2:38 am Post subject: Re: How to pass this template template argument? (MSVC++ 8 e |
|
|
"Victor Bazarov" <v.Abazarov (AT) comAcast (DOT) net> wrote in message
news:7qednb47j5t-XEfenZ2dnUVZ_tKdnZ2d (AT) comcast (DOT) com
| Quote: | John Carson wrote:
Strange. It won't compile for me on either VC++ Express 2005 or a
Release Candidate of VS Team System.
Compiled for me on Express 2005. Are you sure you used the same code?
|
You are using /Za aren't you? It seems that makes the difference. (It would
be nice to think that this difference is a direct result of /Za giving more
compliant behaviour. I have a suspicion, however, that it is actually a
result of /Za being less tested, so that the 2003 behaviour wasn't changed.)
--
John Carson |
|
| Back to top |
|
 |
John Carson Guest
|
Posted: Sat Jan 28, 2006 2:38 am Post subject: Re: How to pass this template template argument? (MSVC++ 8 e |
|
|
"Victor Bazarov" <v.Abazarov (AT) comAcast (DOT) net> wrote in message
news:7qednb47j5t-XEfenZ2dnUVZ_tKdnZ2d (AT) comcast (DOT) com
| Quote: | John Carson wrote:
Strange. It won't compile for me on either VC++ Express 2005 or a
Release Candidate of VS Team System.
Compiled for me on Express 2005. Are you sure you used the same code?
-------------- this is from your post
template<typename T> class Base
{
};
template<typename U, template<typename> class TempTemp> class
Derived;
template<typename V> class Derived<V, Base> : public Base<V
{
public:
template <typename W> void Fun(Derived<W, Base>&) // <-- error!?!
{
}
};
// -------------- this I added...
int main()
{
Derived<int,Base> di;
Derived<char,Base> dc;
di.Fun(dc);
}
|
Straight copy and paste from what you just posted above and it won't compile
(and my first error is the one reported by the OP).
--
John Carson |
|
| Back to top |
|
 |
Victor Bazarov Guest
|
Posted: Sat Jan 28, 2006 2:38 am Post subject: Re: How to pass this template template argument? (MSVC++ 8 e |
|
|
John Carson wrote:
| Quote: | "Victor Bazarov" <v.Abazarov (AT) comAcast (DOT) net> wrote in message
news:7qednb47j5t-XEfenZ2dnUVZ_tKdnZ2d (AT) comcast (DOT) com
John Carson wrote:
Strange. It won't compile for me on either VC++ Express 2005 or a
Release Candidate of VS Team System.
Compiled for me on Express 2005. Are you sure you used the same
code?
You are using /Za aren't you? It seems that makes the difference.
|
Yes, most certainly. If "language extensions" are disabled, I get to
check the actual compliance (and it's not bad). Since I am not usually
compiling any Windows API/SDK (which needs extensions), /Za is it.
| Quote: | (It
would be nice to think that this difference is a direct result of /Za
giving more compliant behaviour. I have a suspicion, however, that it
is actually a result of /Za being less tested, so that the 2003
behaviour wasn't changed.)
|
I don't understand this, sorry. Perhaps further discussions on VC++
should continue in 'microsoft.public.vc.language'...
V
--
Please remove capital As from my address when replying by mail |
|
| Back to top |
|
 |
John Carson Guest
|
Posted: Sat Jan 28, 2006 1:15 pm Post subject: Re: How to pass this template template argument? (MSVC++ 8 e |
|
|
"Victor Bazarov" <v.Abazarov (AT) comAcast (DOT) net> wrote in message
news:i5SdnXlChNgeSkfenZ2dnUVZ_sidnZ2d (AT) comcast (DOT) com
| Quote: | John Carson wrote:
"Victor Bazarov" <v.Abazarov (AT) comAcast (DOT) net> wrote in message
news:7qednb47j5t-XEfenZ2dnUVZ_tKdnZ2d (AT) comcast (DOT) com
John Carson wrote:
Strange. It won't compile for me on either VC++ Express 2005 or a
Release Candidate of VS Team System.
Compiled for me on Express 2005. Are you sure you used the same
code?
You are using /Za aren't you? It seems that makes the difference.
Yes, most certainly. If "language extensions" are disabled, I get to
check the actual compliance (and it's not bad). Since I am not
usually compiling any Windows API/SDK (which needs extensions), /Za
is it.
(It
would be nice to think that this difference is a direct result of /Za
giving more compliant behaviour. I have a suspicion, however, that it
is actually a result of /Za being less tested, so that the 2003
behaviour wasn't changed.)
I don't understand this, sorry. Perhaps further discussions on VC++
should continue in 'microsoft.public.vc.language'...
|
On further investigation, I appear to be wrong. Consider this simpler case:
template<class T>
struct Base
{
Base(T arg) : t(arg)
{}
T t;
};
template<class T>
struct Derived : Base<T>
{
Derived(T arg) : Base(arg) // compilation failure here
{}
};
int main()
{
Derived<int> d(235);
}
This (correctly) fails to compile with /Za, but will compile without it.
The change needed to get it to compile with (or without) /Za is to change
the Derived constructor so that Base has a template argument:
Derived(T arg) : Base<T>(arg)
{}
For the original
Derived(T arg) : Base(arg)
{}
we get the following error message with /Za, among others:
'Derived<T>' : illegal member initialization: 'Base' is not a base or member
Thus /Za is controlling whether or not Base is interpreted as Base<T> within
Derived, which is the same issue as in the OP's code. However, I have been
unable to find any documentation of this effect of /Za.
--
John Carson |
|
| Back to top |
|
 |
Niels Dekker - no reply a Guest
|
Posted: Sat Jan 28, 2006 3:05 pm Post subject: Re: How to pass this template template argument? (MSVC++ 8 e |
|
|
Thanks, Victor and John, you really helped me out!
Victor Bazarov wrote:
| Quote: | I just added this: [...]
And compiled it successfully with VC++ v8.0.
Please next time post the _complete_ code if you want us to be
able to help you with any particular problem.
|
Sorry for not including my -empty- main() function. I hadn't realized
that this compile error only occurs when Microsoft language extensions
are enabled.
John Carson wrote:
| Quote: | If you wanted to refer to the template Base inside Base, then you
could use ::Base.
|
Apparently I can also use ::Base inside Derived, and this will fix my
problem! The following compiles for MSVC++ 8 (both with and without
language extensions), as well as MSVC++ 7.1 and Comeau (online). And I
guess it's still correct C++ as well!
template <typename T> class Base
{
};
template <typename U, template <typename> class TempTemp>
class Derived;
template <typename V>
class Derived<V, Base> : public Base<V>
{
public:
template <typename W> void Fun(Derived<W, ::Base>&) // <-- okay!
{
}
};
int main()
{
}
Thanks again,
Niels Dekker
www.xs4all.nl/~nd/dekkerware |
|
| Back to top |
|
 |
John Carson Guest
|
Posted: Sat Jan 28, 2006 3:05 pm Post subject: Re: How to pass this template template argument? (MSVC++ 8 e |
|
|
"Niels Dekker - no reply address" <unknown (AT) this (DOT) is.invalid> wrote in
message news:43DB82CB.115704B6 (AT) this (DOT) is.invalid
| Quote: | Thanks, Victor and John, you really helped me out!
Victor Bazarov wrote:
I just added this: [...]
And compiled it successfully with VC++ v8.0.
Please next time post the _complete_ code if you want us to be
able to help you with any particular problem.
Sorry for not including my -empty- main() function. I hadn't realized
that this compile error only occurs when Microsoft language extensions
are enabled.
John Carson wrote:
If you wanted to refer to the template Base inside Base, then you
could use ::Base.
Apparently I can also use ::Base inside Derived, and this will fix my
problem!
|
I know. I said that in my post.
--
John Carson |
|
| Back to top |
|
 |
Niels Dekker - no reply a Guest
|
Posted: Sat Jan 28, 2006 4:00 pm Post subject: Re: How to pass this template template argument? (MSVC++ 8 e |
|
|
John Carson wrote:
| Quote: | Niels Dekker wrote:
Apparently I can also use ::Base inside Derived, and this will fix my
problem!
I know. I said that in my post.
|
You're right :-)
Kind regards,
Niels Dekker |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|