Topic: Pointer to member contravariance and template non-type arguments


Author: =3D?ISO-8859-1?Q?Joaqu=3DEDn_M_L=3DF3pez_Mu=3DF1oz?=3D <joaquin@tid.e=.s>
Date: Tue, 11 May 2010 15:39:59 CST
Raw View
[This is a slight reformulation of a post I sent to this group in 2007
almost without any response.]

The following piece of code is legal C++:

struct A
{
 int x;
};

struct B:A{};

int main()
{
 int B::* p&B::x;
}

which is reasonable enough, as A::x is part of B public interface via
inheritance. Perhaps a little metaphorically, we can regard this
aliasing of a pointer to member of base as a pointer to
member of derived like a sort of contravariance rule.
But in the context of template non-type arguments, the rule does not
apply:

struct A
{
 int x;
};

struct B:A{};

template<int B::*Ptr>
struct foo{};

int main()
{
 // error: argument of type "int A::*" is incompatible with
 // template parameter of type "int B::*"
 foo<&B::x> f;
}

There's a paragraph in the standard that explicitly bans this
conversion (14.4.2/5 [temp.arg.nontype] in the latest C++0x
draft):

 "for a non-type template-parameter of type pointer to object,
 qualification conversions (4.4) and the array-to-pointer conversion
 (4.2) are applied; if the template-argument is of type
std::nullptr_t,
 the null pointer conversion (4.10) is applied. [ Note: In
particular,
 neither the null pointer conversion for a zero-valued integral
 constant expression (4.10) nor the derived-to-base conversion
 (4.10) are applied. [...]]"

Is there any sensible reason for this banning that escapes me?
Why here (template args) and not anywhere else?

Thanks in advance,

Joaqu=EDn M L=F3pez Mu=F1oz
Telef=F3nica, Investigaci=F3n y Desarrollo


--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use
mailto:std-c++@netlab.cs.rpi.edu<std-c%2B%2B@netlab.cs.rpi.edu>
]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Edward Diener <eldiener@tropicsoft.invalid>
Date: Wed, 12 May 2010 12:09:47 CST
Raw View
On 5/11/2010 5:39 PM, =?ISO-8859-1?Q?Joaqu=EDn_M_L=F3pez_Mu=F1oz?=
wrote:

> [This is a slight reformulation of a post I sent to this group in 2007
> almost without any response.]
>
> The following piece of code is legal C++:
>
> struct A
> {
>  int x;
> };
>
> struct B:A{};
>
> int main()
> {
>  int B::* p&B::x;
>

I think you meant

int B::* p = &B::x;

here.

}
>
snipped...

--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use
mailto:std-c++@netlab.cs.rpi.edu<std-c%2B%2B@netlab.cs.rpi.edu>
]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: David Krauss <potswa@gmail.com>
Date: Wed, 12 May 2010 12:29:13 CST
Raw View
On May 11, 4:39 pm, =?ISO-8859-1?Q?Joaqu=EDn_M_L=F3pez_Mu=F1oz?
= <joaq...@tid.e=.s> wrote:
> [This is a slight reformulation of a post I sent to this group in 2007
> almost without any response.]

Google turns up only
http://groups.google.com/group/comp.std.c++/browse_thread/thread/6ee50a2a95fea3ef/668e110bfbf41859?lnk=gst&q=joaquin+lopez+munoz#668e110bfbf41859
which is from Jan 2006 and no recorded responses.

Mods, is it possible to switch the post forwarding program to UTF-8?
The Google web interface, at least, murders all accented characters...

>  neither the null pointer conversion for a zero-valued integral
>  constant expression (4.10) nor the derived-to-base conversion
>  (4.10) are applied. [...]]"
>
> Is there any sensible reason for this banning that escapes me?
> Why here (template args) and not anywhere else?

I think you mean 14.3.2/5, and a different bullet point. The one you
quoted refers to regular pointers, not pointers to members. The only
change I see in the FCD relative to C++03 is the provision for
nullptr_t conversion.

I recall working around this by passing the derived class type as an
additional parameter, and using that to declare the precise type of
the pointer to derived member.


--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use
mailto:std-c++@netlab.cs.rpi.edu<std-c%2B%2B@netlab.cs.rpi.edu>
]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: =?ISO-8859-1?Q?Joaqu=EDn_M_L=F3pez_Mu=F1oz?= <joaquin@tid.es>
Date: Thu, 13 May 2010 11:29:33 CST
Raw View
On 12 mayo, 20:09, Edward Diener <eldie...@tropicsoft.invalid> wrote:
> On 5/11/2010 5:39 PM, Joaquin M Lopez Munoz
> wrote:
>
>
>
> > [This is a slight reformulation of a post I sent to this group in 2007
> > almost without any response.]
> >
> > The following piece of code is legal C++:
> >
> > [...]
> >
> >  int B::* p&B::x;
>
> I think you meant
>
> int B::* p = &B::x;
>
> here.

Yes, of course. Thank you for the correction.

Joaqu   n M L   pez Mu   oz
Telef   nica, Investigaci   n y Desarrollo


--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: =3D?ISO-8859-1?Q?Joaqu=3DEDn_M_L=3DF3pez_Mu=3DF1oz?=3D <joaquin@tid.e=.s>
Date: Thu, 13 May 2010 12:06:16 CST
Raw View
On 12 mayo, 20:29, David Krauss <pot...@gmail.com> wrote:
> On May 11, 4:39 pm, Joaquin M Lopez Munoz wrote:
> > [This is a slight reformulation of a post I sent to this group in 2007
> > almost without any response.]
>
> Google turns up only http://groups.google.com/[...]
> which is from Jan 2006 and no recorded responses.


Yes, this was the first time I asked about this. I reposted on Feb
2007:

http://groups.google.com/group/comp.std.c++/browse_frm/thread/472d357280d1f=
435/79ba365c61ac1474?#79ba365c61ac1474

and again no clarification was provided.

> >  neither the null pointer conversion for a zero-valued integral
> >  constant expression (4.10) nor the derived-to-base conversion
> >  (4.10) are applied. [...]]"
>
> > Is there any sensible reason for this banning that escapes me?
> > Why here (template args) and not anywhere else?
>
> I think you mean 14.3.2/5, and a different bullet point. The one you
> quoted refers to regular pointers, not pointers to members. The only
> change I see in the FCD relative to C++03 is the provision for
> nullptr_t conversion.

14.4.2/5 is the location in the latest C++0x drafts, 14.3.2/5 the
location
in C++98 and C++03 standards. You're right I misquoted the relevant
point bullets, the one in point is:

 "For a non-type template-parameter of type pointer to data member,
 qualification conversions (4.4) are applied; if the template-
argument
 is of type std::nullptr_t, the null member pointer conversion (4.11)
 is applied."

Thank you,

Joaqu=EDn M L=F3pez Mu=F1oz
Telef=F3nica, Investigaci=F3n y Desarrollo


--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use
mailto:std-c++@netlab.cs.rpi.edu<std-c%2B%2B@netlab.cs.rpi.edu>
]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "=?iso-8859-1?B?Sm9hcXXtbiBNIEzzcGV6IE118W96?=" <joaquin@tid.es>
Date: Sat, 10 Feb 2007 13:00:48 CST
Raw View
[I posted this question here about a year ago without any response,
trying my luck again]

The following piece of code is legal C++:

struct A
{
  int x;
};

struct B:A{};

int main()
{
  int B::* p&B::x;
}

which is reasonable enough, as A::x is part of B public interface via
inheritance. Perhaps a little metaphorically, we can regard this
aliasing of a pointer to member of base as a pointer to
member of derived like a sort of contravariance rule.
But in the context of template non-type arguments, the rule does not
apply:

struct A
{
  int x;
};

struct B:A{};

template<int B::*Ptr>
struct foo{};

int main()
{
  // error: argument of type "int A::*" is incompatible with
  // template parameter of type "int B::*"
  foo<&B::x> f;
}

I'm sure there's some place in the standard implicitly or explicitly
banning the conversion in this particular context (though I couldn't
find it). My questions are:

* Is there any sensible reason for this banning that escapes me?
Why here (template args) and not anywhere else?
* If not, would it be a good idea to file a DR?

Thanks in advance,

Joaqu   n M L   pez Mu   oz
Telef   nica, Investigaci   n y Desarrollo


---
[ 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.comeaucomputing.com/csc/faq.html                      ]





Author: Gennaro Prota <gennaro.prota@yahoo.com>
Date: Sat, 10 Feb 2007 14:49:54 CST
Raw View
On Sat, 10 Feb 2007 13:00:48 CST, Joaqu   n M L   pez Mu   oz wrote:

>[I posted this question here about a year ago without any response,
>trying my luck again]

Gulp! How could you wait so much :-) I'm going to reply even if I
don't know the answer, as that tends to generate traffic and thoughts
:-)

>[...]
>But in the context of template non-type arguments, the rule does not
>apply:
>
>struct A
>{
>  int x;
>};
>
>struct B:A{};
>
>template<int B::*Ptr>
>struct foo{};
>
>int main()
>{
>  // error: argument of type "int A::*" is incompatible with
>  // template parameter of type "int B::*"
>  foo<&B::x> f;
>}
>
>I'm sure there's some place in the standard implicitly or explicitly
>banning the conversion in this particular context (though I couldn't
>find it).

In 14.3.2 [temp.arg.nontype] par. 5 there is:

  For a non-type template-parameter of type pointer to data
  member, qualification conversions (4.4) are applied.

I think the leading sentence of the paragraph is meant to say:

  *Only* the following conversions are performed...

(not sure whether "only" is redundant, but I'd have inserted it :-))

> My questions are:
>
>* Is there any sensible reason for this banning that escapes me?
>Why here (template args) and not anywhere else?
>* If not, would it be a good idea to file a DR?

Perhaps. If you file one (but please wait for people more
knowledgeable than me to voice their opinion) do not forget to mention
core issue 203 and 247, which are related.

Genny.

---
[ 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.comeaucomputing.com/csc/faq.html                      ]





Author: "=?iso-8859-1?B?Sm9hcXXtbiBNIEzzcGV6IE118W96?=" <joaquin@tid.es>
Date: Tue, 10 Jan 2006 02:50:29 CST
Raw View
The following piece of code is legal C++:

struct A
{
  int x;
};

struct B:A{};

int main()
{
  int B::* p=&B::x;
}

which is reasonable enough, as A::x is part of B public interface via
inheritance. Perhaps a little metaphorically, we can regard this
aliasing of a pointer to member of base as a pointer to
member of derived like a sort of contravariance rule.
But in the context of template non-type arguments, the rule does not
apply:

struct A
{
  int x;
};

struct B:A{};

template<int B::*Ptr>
struct foo{};

int main()
{
  // error: argument of type "int A::*" is incompatible with
  // template parameter of type "int B::*"
  foo<&B::x> f;
}

I'm sure there's some place in the standard implicitly or explicitly
banning the conversion in this particular context (though I couldn't
find it). My questions are:

* Is there any sensible reason for this banning that escapes me?
Why here (template args) and not anywhere else?
* If not, would it be a good idea to file a DR?

Thanks in advance,

Joaqu   n M L   pez Mu   oz
Telef   nica, Investigaci   n y Desarrollo


---
[ 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.jamesd.demon.co.uk/csc/faq.html                       ]