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 

partial specialization problem

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
Vladimir Marko
Guest





PostPosted: Wed Apr 20, 2005 8:52 pm    Post subject: partial specialization problem Reply with quote



14.5.4/9 places some restrictions on the partial specialization
template parameters and arguments. However, I can't find there
anything that would make the following snippet ill-formed:

template <typename>
struct extract_type { };

template <typename T,template
struct extract_type<Templ{
typedef T type;
};

But both gcc 3.4 and Coemau Online complain, gcc saying that
template parameter 'T' is not used in partial specialization
and Comeau saying that the template parameter 't' depends on
another template parameter. Do I miss something?

And given the code

template <typename T,template
void foo(Templ<t>) { }

template <int i>
struct int_ { static const int value=i; };

int main(){
foo(int_<1>()); // gcc, Comeau Online: deduction failure
}

is the deduction really supposed to fail?

Regards,
Vladimir Marko


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Hyman Rosen
Guest





PostPosted: Thu Apr 21, 2005 8:52 am    Post subject: Re: partial specialization problem Reply with quote



Vladimir Marko wrote:
Quote:
Comeau saying that the template parameter 't' depends on
another template parameter. Do I miss something?

Yes; 14.5.4/9p2 says
"The type of a template parameter corresponding to a
specialized non-type argument shall not be dependent
on a parameter of the specialization."

Quote:
is the deduction really supposed to fail?

Yes; 14.8.2.4/4p2 says that one nondeduced context is
"A type that is a template-id in which one or more of
the template-arguments is an expression that references
a template-parameter."

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Graeme Prentice
Guest





PostPosted: Thu Apr 21, 2005 12:09 pm    Post subject: Re: partial specialization problem Reply with quote





In my other post in this thread I said
"You can call foo<int> or you could specialize foo for some of the
arithmetic types if that's all you need to use it for."

I meant overload, not specialize.

Graeme

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Graeme Prentice
Guest





PostPosted: Thu Apr 21, 2005 12:10 pm    Post subject: Re: partial specialization problem Reply with quote

On 20 Apr 2005 16:52:13 -0400, Vladimir Marko wrote:

Quote:
14.5.4/9 places some restrictions on the partial specialization
template parameters and arguments. However, I can't find there
anything that would make the following snippet ill-formed:

template <typename
struct extract_type { };

template struct extract_type<Templ{
typedef T type;
};

But both gcc 3.4 and Coemau Online complain, gcc saying that
template parameter 'T' is not used in partial specialization
and Comeau saying that the template parameter 't' depends on
another template parameter. Do I miss something?


A more recent edition of the Comeau compiler says "T is not used"
instead of the message you give above.

With a class partial specialization, there is no way to explicitly tell
the compiler what types/values etc to substitute for the parameters of
the specialization e.g. when you use the extract_type class template you
can write something like extract_type<int> and specify just a single
template argument - whereas the partial specialization has three
template parameters. Hence the compiler has to deduce all the
types/values/templates in the partial specialization parameter list -
if some of these aren't used in the partial specialization argument list
then there's no way they can be deduced so deduction fails.

14.5.4.1/2 requires that the template arguments of the partial
specialization ( Templ<t> in you example above ) be able to be deduced
from the actual template argument list ( e.g. int - in my example of
extract_type<int> above ). 14.8.2 (Deduction) requires all template
parameter types to be known even if they're not used. With function
templates you can explicitly specify the unused types but you can't do
that with class partial specializations.

Deduction also occurs with partial ordering and current deduction rules
for partial ordering also require the types/values/templates of all
parameters to be known but I think a future amendment to the rules of
partial ordering will allow types that aren't used to remain unknown and
not cause deduction to fail - this won't apply during the initial
selection of the partial specializations that participate in partial
ordering though.

You can write the above code like this

template <typename>
struct extract_type { };

template <typename T,template
struct extract_type<Templ{
typedef T type;
};


Quote:

And given the code

template <typename T,template void foo(Templ<t>) { }

template <int i
struct int_ { static const int value=i; };

int main(){
foo(int_<1>()); // gcc, Comeau Online: deduction failure
}

is the deduction really supposed to fail?

As Hyman said, Templ<t> is a non-deduced context.
You can call foo<int> or you could specialize foo for some of the
arithmetic types if that's all you need to use it for.

I can't think of any way to extract the type of the non type argument
from the "parent" type.

Some problems with compiler interpretations of 14.5.4/9 were discussed
here
http://makeashorterlink.com/?H2A753EEA

but the Comeau compiler no longer gives an error for the following code
that was mentioned in the above link.

template<typename T, T N, int X>
struct base {};
template<typename T, T N>
struct base<T,N,0> {};
int main() {}

Graeme

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Vladimir Marko
Guest





PostPosted: Thu Apr 21, 2005 12:10 pm    Post subject: Re: partial specialization problem Reply with quote

Hyman Rosen wrote:
Quote:
Vladimir Marko wrote:
Comeau saying that the template parameter 't' depends on
another template parameter. Do I miss something?

Yes; 14.5.4/9p2 says
"The type of a template parameter corresponding to a
specialized non-type argument shall not be dependent
on a parameter of the specialization."

I read that one and IIRC it doesn't apply to my snippet. The
standard makes a very clear distinction between a "parameter"
and an "argument". The only "argument" I have is "Templ<t>"
and it's not a "non-type argument". So I ask again: Do I miss
something? And include the details please. (May be it's just
my english what's wrong.)

Quote:
is the deduction really supposed to fail?

Yes; 14.8.2.4/4p2 says that one nondeduced context is
"A type that is a template-id in which one or more of
the template-arguments is an expression that references
a template-parameter."

I remember reading that bullet and having no idea when does it
apply. Now it finaly makes sense to me.

Vladimir Marko


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Vladimir Marko
Guest





PostPosted: Thu Apr 21, 2005 4:44 pm    Post subject: Re: partial specialization problem Reply with quote

Graeme Prentice wrote:
Quote:
On 20 Apr 2005 16:52:13 -0400, Vladimir Marko wrote:

14.5.4/9 places some restrictions on the partial specialization
template parameters and arguments. However, I can't find there
anything that would make the following snippet ill-formed:

template <typename
struct extract_type { };

template struct extract_type<Templ{
typedef T type;
};
[snip]
14.5.4.1/2 requires that the template arguments of the partial
specialization ( Templ<t> in you example above ) be able to be
deduced
from the actual template argument list ( e.g. int - in my example of
extract_type<int> above ). 14.8.2 (Deduction) requires all template
parameter types to be known even if they're not used. With function
templates you can explicitly specify the unused types but you can't
do
that with class partial specializations.

It is clear that the specialization can never be chosen and
it will never be more or less specialized than another one.
So the code is completely useless. But I'm still curious:
is the code really ill-formed?

Quote:
I can't think of any way to extract the type of the non type argument
from the "parent" type.

If I could at least extract the type of nested "static const
some-type value". But it seems that even for this simplified
task I'll have to wait for decltype.

Vladimir Marko


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Graeme Prentice
Guest





PostPosted: Sat Apr 23, 2005 2:22 am    Post subject: Re: partial specialization problem Reply with quote

On 21 Apr 2005 12:44:38 -0400, Vladimir Marko wrote:

Quote:
Graeme Prentice wrote:
On 20 Apr 2005 16:52:13 -0400, Vladimir Marko wrote:

14.5.4/9 places some restrictions on the partial specialization
template parameters and arguments. However, I can't find there
anything that would make the following snippet ill-formed:

template <typename
struct extract_type { };

template struct extract_type<Templ{
typedef T type;
};
[snip]
14.5.4.1/2 requires that the template arguments of the partial
specialization ( Templ<t> in you example above ) be able to be
deduced
from the actual template argument list ( e.g. int - in my example of
extract_type<int> above ). 14.8.2 (Deduction) requires all template
parameter types to be known even if they're not used. With function
templates you can explicitly specify the unused types but you can't
do
that with class partial specializations.

It is clear that the specialization can never be chosen and
it will never be more or less specialized than another one.
So the code is completely useless. But I'm still curious:
is the code really ill-formed?

Yes it is ill-formed. For your case to be legal, the compiler would
have to deduce the type of the template parameter T from the type of the
non-type argument t. This kind of deduction is disallowed in
14.8.2.4/12 - I think this rule would apply here too. I don't know why
this is disallowed but presumably there's a reason. Hence even if the
problem with "T not used" was resolved by arguing that T is "used" in
subsequent template parameters, it's type cannot be deduced so the code
is ill-formed.

As you're suggesting, it *ought* to be possible to have a partial
specialization of extract_type<Templ that matches any template
class type with a single non-type argument. The language appears not to
allow this. You could consider asking on comp.std.c++ whether this case
should be handled somehow and what the reason for 14.8.2.4/12 is. The
use for such a feature seems more in the meta-programming realm than in
the "real" world.


Quote:

I can't think of any way to extract the type of the non type argument
from the "parent" type.

If I could at least extract the type of nested "static const
some-type value". But it seems that even for this simplified
task I'll have to wait for decltype.

I don't understand what you're trying to do. Can you explain in more
detail?

Graeme

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Vladimir Marko
Guest





PostPosted: Tue Apr 26, 2005 9:04 am    Post subject: Re: partial specialization problem Reply with quote

Graeme Prentice wrote:
Quote:
On 21 Apr 2005 12:44:38 -0400, Vladimir Marko wrote:

Graeme Prentice wrote:
On 20 Apr 2005 16:52:13 -0400, Vladimir Marko wrote:
[snip]
It is clear that the specialization can never be chosen and
it will never be more or less specialized than another one.
So the code is completely useless. But I'm still curious:
is the code really ill-formed?

Yes it is ill-formed. For your case to be legal, the compiler would
have to deduce the type of the template parameter T from the type of
the
non-type argument t. This kind of deduction is disallowed in
14.8.2.4/12 - I think this rule would apply here too. I don't know
why
this is disallowed but presumably there's a reason. Hence even if
the
problem with "T not used" was resolved by arguing that T is "used" in
subsequent template parameters, it's type cannot be deduced so the
code
is ill-formed.

You didn't convince me at all. You point to 14.8.2, template
argument deduction, which is completely irrelevant because I
already admitted that the specialization can never be chosen.
I ask whether the declaration/definition of a specialization
that can not be chosen is ill-formed (there is still the
primary template that can be chosen). The idea is that in
struct A;
typedef A A;
the typedef is completely useless but _well-formed_. And the
specialization could be completely useless but well-formed too.
(This question has no real-world use, of course.)

Quote:
As you're suggesting, it *ought* to be possible to have a partial
specialization of extract_type<Templ that matches any template
class type with a single non-type argument. The language appears not
to
allow this. [snip]

That was the original idea. Now I see it doesn't work this way.

Quote:
The use for such a feature seems more in the meta-programming
realm than in the "real" world.

Exactly.

Quote:
I can't think of any way to extract the type of the non type
argument
from the "parent" type.

If I could at least extract the type of nested "static const
some-type value". But it seems that even for this simplified
task I'll have to wait for decltype.

I don't understand what you're trying to do. Can you explain in more
detail?

template <typename T>
struct extract_type{
typedef typename remove_cv_qualifiers<
typename remove_reference<
decltype(T::value)
Quote:
::type
::type type;
};


This extracts the type of a static data member T::value.
For classes like
template this is the same type as the type of the non-type template
parameter.

Vladimir Marko


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Graeme Prentice
Guest





PostPosted: Wed Apr 27, 2005 8:01 am    Post subject: Re: partial specialization problem Reply with quote

On 26 Apr 2005 05:04:58 -0400, Vladimir Marko wrote:

Quote:
Graeme Prentice wrote:
On 21 Apr 2005 12:44:38 -0400, Vladimir Marko wrote:

Graeme Prentice wrote:
On 20 Apr 2005 16:52:13 -0400, Vladimir Marko wrote:
[snip]
It is clear that the specialization can never be chosen and
it will never be more or less specialized than another one.
So the code is completely useless. But I'm still curious:
is the code really ill-formed?

Yes it is ill-formed. For your case to be legal, the compiler would
have to deduce the type of the template parameter T from the type of
the
non-type argument t. This kind of deduction is disallowed in
14.8.2.4/12 - I think this rule would apply here too. I don't know
why
this is disallowed but presumably there's a reason. Hence even if
the
problem with "T not used" was resolved by arguing that T is "used" in
subsequent template parameters, it's type cannot be deduced so the
code
is ill-formed.

You didn't convince me at all. You point to 14.8.2, template
argument deduction, which is completely irrelevant because I
already admitted that the specialization can never be chosen.
I ask whether the declaration/definition of a specialization
that can not be chosen is ill-formed (there is still the
primary template that can be chosen). The idea is that in
struct A;
typedef A A;
the typedef is completely useless but _well-formed_. And the
specialization could be completely useless but well-formed too.
(This question has no real-world use, of course.)

The error message given by GCC in your original post is correct -
template parameter 'T' is not used in partial specialization

The latest edition of the Comeau compiler says
error: template parameter "T" is not used in template argument list of
class template

VC7.1 says
error C2764: 'T' : template parameter not used in partial specialization
'extract_type<Templ'

The standard doesn't explicitly say that the code is ill-formed, however
since the type of T can never be deduced (because it isn't used in the
argument list) the code is useless and a reasonable compiler would give
a diagnostic because useless code indicates a programmer error.

I mentioned 14.8.2 because it could be argued that T is "used" further
on in the template parameter list - and its type could be deduced from
the type of the non-type argument. 14.8.2.4/12 disallows this kind of
deduction. I suspect this is because it was considered "not worth the
effort and burden on the compiler writer", but that's just a guess.


Quote:

As you're suggesting, it *ought* to be possible to have a partial
specialization of extract_type<Templ that matches any template
class type with a single non-type argument. The language appears not
to
allow this. [snip]

That was the original idea. Now I see it doesn't work this way.

The use for such a feature seems more in the meta-programming
realm than in the "real" world.

Exactly.

I can't think of any way to extract the type of the non type
argument
from the "parent" type.

If I could at least extract the type of nested "static const
some-type value". But it seems that even for this simplified
task I'll have to wait for decltype.

I don't understand what you're trying to do. Can you explain in more
detail?

template <typename T
struct extract_type{
typedef typename remove_cv_qualifiers
typename remove_reference
decltype(T::value)
::type
::type type;
};

This extracts the type of a static data member T::value.
For classes like
template this is the same type as the type of the non-type template
parameter.


Well I still don't understand what you're trying to do. From the
information you're giving me you could just as easily declare a typedef
as a member of struct int_
typedef int value_type;
static const value_type value = i_;
and use value_type instead of extract_type/decltype.
Since this is too obvious, there must be some information I'm missing.

Your extract_type/decltype code above is "assuming" that type T is a
class with a member named value - how do you know T has a member named
value and how do you know that the type of "value" is the same as the
type of the non-type parameter of the struct int_ class.

Graeme

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Vladimir Marko
Guest





PostPosted: Thu Apr 28, 2005 12:36 pm    Post subject: Re: partial specialization problem Reply with quote


Graeme Prentice wrote:
[snip]
Quote:
The standard doesn't explicitly say that the code is ill-formed,
however
since the type of T can never be deduced (because it isn't used in
the
argument list) the code is useless

I was trying to say just that ever since I read the 14.8.2.4/4
mentioned by Hyman Rosen.

Quote:
and a reasonable compiler would give
a diagnostic because useless code indicates a programmer error.

Strictly speaking a _conforming_ compiler should not reject
a well-formed code, a warning would be appropriate. As we know
compilers do not reject non-void returning functions without
a return statement either.

[snip]
Quote:
This extracts the type of a static data member T::value.
For classes like
template <int i_> struct int_{ static const int value=i_; };
this is the same type as the type of the non-type template
parameter.


Well I still don't understand what you're trying to do. From the
information you're giving me you could just as easily declare a
typedef
as a member of struct int_
typedef int value_type;
static const value_type value = i_;
and use value_type instead of extract_type/decltype.
Since this is too obvious, there must be some information I'm
missing.


Sometimes I miss the obvious. This time I did put the typedef
into a traits class that I need for additional informations
anyway. Moving it where it belongs won't be a problem. Thanks.

Regards,
Vladimir Marko


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) 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.