Topic: Is this using declaration ill-formed?


Author: "Johannes Schaub (litb)" <schaub-johannes@web.de>
Date: Mon, 16 Aug 2010 14:06:56 CST
Raw View
14.5.2/7: "A using-declaration in a derived class cannot refer to a
specialization of a template conversion function in a base class."

Does this make the following code ill-formed?

struct A {
 template<typename T> operator T();
 operator int();
};

struct B : A { using A::operator int; };


--
[ 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?Daniel_Kr=FCgler?= <daniel.kruegler@googlemail.com>
Date: Mon, 16 Aug 2010 20:28:54 CST
Raw View
On 16 Aug., 22:06, "Johannes Schaub (litb)" <schaub-johan...@web.de>
wrote:
> 14.5.2/7: "A using-declaration in a derived class cannot refer to a
> specialization of a template conversion function in a base class."
>
> Does this make the following code ill-formed?
>
> struct A {
>  template<typename T> operator T();
>  operator int();
>
> };
>
> struct B : A { using A::operator int; };

This should be well-formed. The using declaration
unambiguously refers to the non-template operator
int. There exists just no way to define a using-declaration
that refers to a particular specialization of a template
conversion function. The non-normative note in 7.3.3/4
is intended to clarify this:

"Since specializations of member templates for conversion
functions are not found by name lookup, they are not
considered when a using-declaration specifies a
conversion function (14.5.2)."

[Thanks to Mike Miller for the proper reference of the note]

HTH & Greetings from Bremen,

- Daniel Kr   gler



--
[ 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: "Johannes Schaub (litb)" <schaub-johannes@web.de>
Date: Mon, 16 Aug 2010 20:28:21 CST
Raw View
Johannes Schaub (litb) wrote:

> 14.5.2/7: "A using-declaration in a derived class cannot refer to a
> specialization of a template conversion function in a base class."
>
> Does this make the following code ill-formed?
>
> struct A {
>  template<typename T> operator T();
>  operator int();
> };
>
> struct B : A { using A::operator int; };
>

I see two interpretations:

Option 1:
----------

- During determining the meaning of the name, argument deduction for
template conversion functions is not done and only template conversion
functions or non-specialization conversion functions are found:

struct A {
 template<typename T> operator int(); // #1
 template<typename T> operator T(); // #2
 operator int(); // #3
};

struct B : A {
 // only specifies the name of #1 and #3
 using A::operator int;
};

Option 2:
----------

- After determining the meaning of the name, if the name refers to a
template conversion function specialization, the program is ill-formed.

struct A {
 template<typename T> operator int(); // #1
 template<typename T> operator T(); // #2
 operator int(); // #3
};

struct B : A {
 // ill-formed, because it refers to a specialization of #2.
 using A::operator int;
};

------------------------

Subsequently, i found a note in 7.3.3/4 which indicates the first option is
taken:

"Since specializations of member templates for conversion functions are not
found by name lookup, they are not considered when a using-declaration
specifies a conversion function"

This says what the intent of the standard is, and sort of answers my
question i think. If anyone knows normative wording for it, i would still
like to read about it, though.

--
[ 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?Daniel_Kr=3DFCgler?=3D <daniel.kruegler@googlemail.c=.om>
Date: Tue, 17 Aug 2010 11:45:33 CST
Raw View
On Aug 17, 4:28 am, "Johannes Schaub (litb)" <schaub-johan...@web.de>
wrote:
> Johannes Schaub (litb) wrote:
> > 14.5.2/7: "A using-declaration in a derived class cannot refer to a
> > specialization of a template conversion function in a base class."
>
> > Does this make the following code ill-formed?
>
> > struct A {
> >  template<typename T> operator T();
> >  operator int();
> > };
>
> > struct B : A { using A::operator int; };
>
> I see two interpretations:
>
> Option 1:
> ----------
>
> - During determining the meaning of the name, argument deduction for
> template conversion functions is not done and only template conversion
> functions or non-specialization conversion functions are found:
>
> struct A {
>  template<typename T> operator int(); // #1
>  template<typename T> operator T(); // #2
>  operator int(); // #3
> };
>
> struct B : A {
>  // only specifies the name of #1 and #3
>  using A::operator int;
> };

This is correct, using-declarations use name-lookup (7.3.3/3), but
14.5.2/7 specifically excludes template specializations of conversion
functions in a base class.

> Option 2:
> ----------
>
> - After determining the meaning of the name, if the name refers to a
> template conversion function specialization, the program is ill-formed.
>
> struct A {
>  template<typename T> operator int(); // #1
>  template<typename T> operator T(); // #2
>  operator int(); // #3
> };
>
> struct B : A {
>  // ill-formed, because it refers to a specialization of #2.
>  using A::operator int;
> };

This is incorrect. The normative wording in 14.5.2/7 does say
"cannot refer" without delegating to "ill-formed", it does also *not*
say "shall not refer". The additional non-normative note should
clarify the intent.

> ------------------------
>
> Subsequently, i found a note in 7.3.3/4 which indicates the first option
is
> taken:
>
> "Since specializations of member templates for conversion functions are
not
> found by name lookup, they are not considered when a using-declaration
> specifies a conversion function"
>
> This says what the intent of the standard is, and sort of answers my
> question i think. If anyone knows normative wording for it, i would still
> like to read about it, though.

Personally I find the normative wording clear, so I have no
idea which further reference should be given.

HTH & Greetings from Bremen,

Daniel Kr=FCgler


--
[ 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: "Johannes Schaub (litb)" <schaub-johannes@web.de>
Date: Thu, 19 Aug 2010 02:08:19 CST
Raw View
=?ISO-8859-1?Q?Daniel_Kr=FCgler?= wrote:

> On Aug 17, 4:28 am, "Johannes Schaub (litb)" <schaub-johan...@web.de>
> wrote:
>> Johannes Schaub (litb) wrote:
>> > 14.5.2/7: "A using-declaration in a derived class cannot refer to a
>> > specialization of a template conversion function in a base class."
>>
>> > Does this make the following code ill-formed?
>>
>> > struct A {
>> >  template<typename T> operator T();
>> >  operator int();
>> > };
>>
>> > struct B : A { using A::operator int; };
>>
>> I see two interpretations:
>>
>> Option 1:
>> ----------
>>
>> - During determining the meaning of the name, argument deduction for
>> template conversion functions is not done and only template conversion
>> functions or non-specialization conversion functions are found:
>>
>> struct A {
>>  template<typename T> operator int(); // #1
>>  template<typename T> operator T(); // #2
>>  operator int(); // #3
>> };
>>
>> struct B : A {
>>  // only specifies the name of #1 and #3
>>  using A::operator int;
>> };
>
> This is correct, using-declarations use name-lookup (7.3.3/3), but
> 14.5.2/7 specifically excludes template specializations of conversion
> functions in a base class.
>
>> Option 2:
>> ----------
>>
>> - After determining the meaning of the name, if the name refers to a
>> template conversion function specialization, the program is ill-formed.
>>
>> struct A {
>>  template<typename T> operator int(); // #1
>>  template<typename T> operator T(); // #2
>>  operator int(); // #3
>> };
>>
>> struct B : A {
>>  // ill-formed, because it refers to a specialization of #2.
>>  using A::operator int;
>> };
>
> This is incorrect. The normative wording in 14.5.2/7 does say
> "cannot refer" without delegating to "ill-formed", it does also *not*
> say "shall not refer". The additional non-normative note should
> clarify the intent.
>

Ah i see. I did not know that there is any intended difference between
"cannot refer" and "shall not refer".

I thought whenever program code constructs a contradiction against
standard's wording, the code is wrong. For example the standard says "The
extern specifier cannot be used in the declaration of class members or
function parameters.", and when we write "void f(extern int a);" then the
code is ill-formed because it contradicts the Standard, trying to apply an
"extern" to the parameter. Likewise, in Option 2, the using declaration
would be ill-formed because it tries to refer to a specialization (14.5.2/6
makes the name in it unconditionally refer to the specialization, without
excluding names in using declarations. *Unless* paragraph 7 is that
exclusion, but this depends on the meaning of "cannot").


>> ------------------------
>>
>> Subsequently, i found a note in 7.3.3/4 which indicates the first option
> is
>> taken:
>>
>> "Since specializations of member templates for conversion functions are
> not
>> found by name lookup, they are not considered when a using-declaration
>> specifies a conversion function"
>>
>> This says what the intent of the standard is, and sort of answers my
>> question i think. If anyone knows normative wording for it, i would still
>> like to read about it, though.
>
> Personally I find the normative wording clear, so I have no
> idea which further reference should be given.
>

The phrase "Since specializations of member templates for conversion
functions are not found by name lookup..." is not a conclusion drawn from
normative text, it seems. Arguably 14.5.2/6 can be seen as a tweak to name-
lookup, that kicks in whenever conversion functions are considered somewhere
during name-lookup (they are not found by "normal" name-lookup because the
equality rules for conversion function names at 3/7 would not work). If the
conclusion in that note follows from normative wording, we will need to
apply it to all name-lookup cases, which will make the examples in the
Standard ill-formed.

So my question is: What are the rules for "cannot" vs "shall not"? It seems
understanding that difference is the key to the solution.

--
[ 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?Daniel_Kr=3DFCgler?=3D <daniel.kruegler@googlemail.c=.om>
Date: Fri, 20 Aug 2010 10:30:42 CST
Raw View
On Aug 19, 10:08 am, "Johannes Schaub (litb)" <schaub-johan...@web.de>
wrote:
> =?ISO-8859-1?Q?Daniel_Kr=FCgler?= wrote:

[..]

> > This is incorrect. The normative wording in 14.5.2/7 does say
> > "cannot refer" without delegating to "ill-formed", it does also *not*
> > say "shall not refer". The additional non-normative note should
> > clarify the intent.
>
> Ah i see. I did not know that there is any intended difference between
> "cannot refer" and "shall not refer".
[..]
> So my question is: What are the rules for "cannot" vs "shall not"? It
seems
> understanding that difference is the key to the solution.

In general, both follow a standardized meaning as described
in Annex H of:

http://preview.tinyurl.com/3a4qh3

> I thought whenever program code constructs a contradiction against
> standard's wording, the code is wrong. For example the standard says "The
> extern specifier cannot be used in the declaration of class members or
> function parameters.", and when we write "void f(extern int a);" then the
> code is ill-formed because it contradicts the Standard, trying to apply a=
n
> "extern" to the parameter. Likewise, in Option 2, the using declaration
> would be ill-formed because it tries to refer to a specialization
(14.5.2/6
> makes the name in it unconditionally refer to the specialization, without
> excluding names in using declarations. *Unless* paragraph 7 is that
> exclusion, but this depends on the meaning of "cannot").

14.5.2/7 does use the normative term "cannot" in the proper
way, because it essentially means that it is impossible to write a
using-declaration that refers to a specialization - the syntax
simply doesn't allow it.

In regards to your question comparing with 7.1.1: In fact, this
is improper standardeze, it should say "shall not", here, because
this is a requirement and a violation causes an ill-formed program.
This looks near editorial to me, because the two situations are
different in regard to capability.

[Mike Miller was so friendly to point out to me that 7.1.1 is
historically very old, directly from the ARM, during that time
the wording terms were not so clear defined as of today.]

HTH & Greetings from Bremen,

Daniel Kr=FCgler


--
[ 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: Pete Becker <pete@versatilecoding.com>
Date: Fri, 20 Aug 2010 10:30:31 CST
Raw View
On 2010-08-18 22:08:19 -0400, Johannes Schaub (litb) said:


> So my question is: What are the rules for "cannot" vs "shall not"? It seems
> understanding that difference is the key to the solution.
>

Broadly speaking, they mean different things. "Cannot" means "is unable to",
for whatever reason. "Shall not" means that the standard prohibits doing it.
The latter can be a reason for the former, although there can be other
reasons, independently.

If I don't have a driver's license, I'm not allowed to drive a car. I "shall
not" drive, hence, I "cannot" drive. If I get my driver's license but don't
have a car, I "cannot" drive, although I'm allowed to.

I suspect, however, that this distinction is not always observed in the
standard.

--
 Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
Standard C++ Library Extensions: a Tutorial and Reference (
www.petebecker.com/tr1book)



[ 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: "Johannes Schaub (litb)" <schaub-johannes@web.de>
Date: Fri, 20 Aug 2010 17:04:28 CST
Raw View
Pete Becker wrote:

> On 2010-08-18 22:08:19 -0400, Johannes Schaub (litb) said:
>
>
>> So my question is: What are the rules for "cannot" vs "shall not"? It
>> seems understanding that difference is the key to the solution.
>>
>
> Broadly speaking, they mean different things. "Cannot" means "is unable
> to", for whatever reason. "Shall not" means that the standard prohibits
> doing it. The latter can be a reason for the former, although there can be
> other reasons, independently.
>
> If I don't have a driver's license, I'm not allowed to drive a car. I
> "shall not" drive, hence, I "cannot" drive. If I get my driver's license
> but don't have a car, I "cannot" drive, although I'm allowed to.
>

Ah thanks for clarifying this. Now i see: The using declaration, although it
could designate the specialization by the lookup rules, it is said to
"cannot" by that paragraph (like you could drive a car, but no car is
available because someone hide it). So the program is valid, and the using
declaration does not consider the specialization.

If it would say "shall not", it would make the program ill-formed, like as
if the police would catch you driving a car without license.


--
[ 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                      ]