C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

How to pass this template template argument? (MSVC++ 8 error

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language (comp.lang.c++)
View previous topic :: View next topic  
Author Message
Niels Dekker - no reply a
Guest





PostPosted: Sat Jan 28, 2006 1:15 am    Post subject: How to pass this template template argument? (MSVC++ 8 error Reply with 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


Kind regards,

Niels Dekker
www.xs4all.nl/~nd/dekkerware
Back to top
Victor Bazarov
Guest





PostPosted: Sat Jan 28, 2006 1:15 am    Post subject: Re: How to pass this template template argument? (MSVC++ 8 e Reply with quote



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





PostPosted: Sat Jan 28, 2006 1:15 am    Post subject: Re: How to pass this template template argument? (MSVC++ 8 e Reply with quote



"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





PostPosted: Sat Jan 28, 2006 1:15 am    Post subject: Re: How to pass this template template argument? (MSVC++ 8 e Reply with quote

"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





PostPosted: Sat Jan 28, 2006 1:15 am    Post subject: Re: How to pass this template template argument? (MSVC++ 8 e Reply with quote

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





PostPosted: Sat Jan 28, 2006 2:38 am    Post subject: Re: How to pass this template template argument? (MSVC++ 8 e Reply with quote

"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





PostPosted: Sat Jan 28, 2006 2:38 am    Post subject: Re: How to pass this template template argument? (MSVC++ 8 e Reply with quote

"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





PostPosted: Sat Jan 28, 2006 2:38 am    Post subject: Re: How to pass this template template argument? (MSVC++ 8 e Reply with quote

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





PostPosted: Sat Jan 28, 2006 1:15 pm    Post subject: Re: How to pass this template template argument? (MSVC++ 8 e Reply with quote

"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





PostPosted: Sat Jan 28, 2006 3:05 pm    Post subject: Re: How to pass this template template argument? (MSVC++ 8 e Reply with quote

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





PostPosted: Sat Jan 28, 2006 3:05 pm    Post subject: Re: How to pass this template template argument? (MSVC++ 8 e Reply with quote

"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





PostPosted: Sat Jan 28, 2006 4:00 pm    Post subject: Re: How to pass this template template argument? (MSVC++ 8 e Reply with quote

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
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language (comp.lang.c++) All times are GMT
Page 1 of 1

 
Jump to:  
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


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.