Is this using-declaration ill-formed?

Discussion in 'C++' started by Johannes Schaub (litb), Aug 16, 2010.

  1. 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::eek:perator int; };
    Johannes Schaub (litb), Aug 16, 2010
    #1
    1. Advertising

  2. 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::eek:perator int; };


    There are two interpretations of this:

    - If the use of the name in a using declaration results in refering to the
    specialization of a template conversion function, or results in an overload
    set that includes such a specialization, the program is ill-formed because a
    using-declaration cannot refer to such a function.

    - To determine the meaning of the name used in a using declaration, template
    conversion functions are ignored, because a using declaration cannot refer
    to a specialization of it, nor (in c++03) to the template itself.

    Both interpretation look viable to me. The note at 7.3.3/4 indicates that
    the second option is taken (and my code would be wellformed then), but is
    there a normative ground for that interpretation - maybe an inherent implied
    meaning of "cannot" in international standards?

    By purely taking the normative wording, both options look roughly equally
    viable to me, and the first looks even a bit more viable.
    Johannes Schaub (litb), Aug 16, 2010
    #2
    1. Advertising

  3. Johannes Schaub (litb) 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::eek:perator int; };

    >
    > There are two interpretations of this:
    >
    > - If the use of the name in a using declaration results in refering to the
    > specialization of a template conversion function, or results in an
    > overload set that includes such a specialization, the program is
    > ill-formed because a using-declaration cannot refer to such a function.
    >
    > - To determine the meaning of the name used in a using declaration,
    > template conversion functions are ignored, because a using declaration
    > cannot refer to a specialization of it, nor (in c++03) to the template
    > itself.
    >


    I should correct: You can refer to the template itself in C++03 too, but it
    makes rather little sense to write such a conversion function where you can:

    struct A { template<typename T> operator int(); };
    struct B : A { using A::eek:perator int; };

    Valid, but since "T" is nondeduced, the utility of it is very doubtly. C++0x
    allows for it to have a default argument...
    Johannes Schaub (litb), Aug 16, 2010
    #3
  4. Johannes Schaub (litb)

    Gil Guest

    I believe your code is ill formed.
    to me 14.5.2/7 is just a clarification of a special case of 7.3.3/5.

    struct B : A { using A::eek:perator _no_name_<int>; } //ill formed
    7.3.3/5

    so my interpretation is 14.5.2/7 should be moved to 7.3.3/5 explaining
    that specialization of conversion operators are still considered
    template-id _as_if they would have a name.

    as I see it, the fact that specializations of member templates for
    conversion functions are not found by name lookup is a totally
    different issue, unrelated to 14.5.2/7. that's why the note about it
    in 7.3.3/4 looks misplaced to me.
    Gil, Aug 16, 2010
    #4
  5. Johannes Schaub (litb) 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::eek:perator int; };

    >
    > There are two interpretations of this:
    >
    > - If the use of the name in a using declaration results in refering to the
    > specialization of a template conversion function, or results in an
    > overload set that includes such a specialization, the program is
    > ill-formed because a using-declaration cannot refer to such a function.
    >
    > - To determine the meaning of the name used in a using declaration,
    > template conversion functions are ignored, because a using declaration
    > cannot refer to a specialization of it, nor (in c++03) to the template
    > itself.
    >


    I guess i'm too fast with pressing "send" with non-moderated groups :) Here
    is what i sent to comp.std.c++, which is more what i meant to write. Please
    forgive my many follow-self-answers. I'm really a bloody usenet-
    nonmoderated-groups starter:

    ##################################

    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::eek:perator 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::eek:perator 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.
    Johannes Schaub (litb), Aug 16, 2010
    #5
  6. On 16/08/2010 21.26, Johannes Schaub (litb) wrote:
    > Johannes Schaub (litb) 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::eek:perator int; };

    >>
    >> There are two interpretations of this:
    >>
    >> - If the use of the name in a using declaration results in refering to the
    >> specialization of a template conversion function, or results in an
    >> overload set that includes such a specialization, the program is
    >> ill-formed because a using-declaration cannot refer to such a function.
    >>
    >> - To determine the meaning of the name used in a using declaration,
    >> template conversion functions are ignored, because a using declaration
    >> cannot refer to a specialization of it, nor (in c++03) to the template
    >> itself.
    >>

    >
    > I should correct: You can refer to the template itself in C++03 too, but it
    > makes rather little sense to write such a conversion function where you can:
    >
    > struct A { template<typename T> operator int(); };
    > struct B : A { using A::eek:perator int; };
    >
    > Valid, but since "T" is nondeduced, the utility of it is very doubtly. C++0x
    > allows for it to have a default argument...


    I haven't checked the standard as thoroughly as this question
    would require but, yes, *off-hand* I'd have expected that if the
    intended meaning was 1 (first bullet above) they would have used
    "shall" or "shall not". Whereas "cannot" is, by strict ISO rules
    (see e.g.

    <http://anubis.dkuug.dk/JTC1/SC22/WG9/isodir3.pdf>

    ) to be taken as "there is no possibility of".

    But...

    a) One wonders what's the point of a "there's no possibility of"
    /outside of an explicative note/ if it follows from other
    normative parts (if it doesn't follow, then why not using
    "shall" or "shall not"?). Where are such normative parts in this
    case?

    b) Not all people who write the C++ standard seem to be aware of
    these (IMHO very fastidious and unsuited) rules. I've certainly
    found usages of "may not" to where a prohibition was meant, for
    instance (an example from memory: the prohibition to replace the
    placement forms of operator new), although the document linked
    to above doesn't allow it.

    --
    Gennaro Prota | name.surname yahoo.com
    Breeze C++ (preview): <https://sourceforge.net/projects/breeze/>
    Do you need expertise in C++? I'm available.
    Gennaro Prota, Aug 16, 2010
    #6
  7. Johannes Schaub (litb)

    James Kanze Guest

    On Aug 16, 9:02 pm, "Johannes Schaub (litb)" <>
    wrote:
    > Johannes Schaub (litb) 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::eek:perator int; };


    > > There are two interpretations of this:


    > > - If the use of the name in a using declaration results in
    > > refering to the specialization of a template conversion
    > > function, or results in an overload set that includes such
    > > a specialization, the program is ill-formed because
    > > a using-declaration cannot refer to such a function.


    > > - To determine the meaning of the name used in a using
    > > declaration, template conversion functions are ignored,
    > > because a using declaration cannot refer to a specialization
    > > of it, nor (in c++03) to the template itself.


    > I guess i'm too fast with pressing "send" with non-moderated
    > groups :) Here is what i sent to comp.std.c++, which is more
    > what i meant to write. Please forgive my many
    > follow-self-answers. I'm really a bloody usenet-
    > nonmoderated-groups starter:


    > ##################################


    > 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


    Note that these are three, unrelated overloaded functions.

    > };


    > struct B : A {
    > // only specifies the name of #1 and #3
    > using A::eek:perator int;


    According to my understanding of what you've posted, #1 will not
    be found, and this only specified #3.

    Note that #1 requires very special syntax to be used anyway.
    Since there is nothing in the declaration which depends on the
    template type, type deduction will always fail on it, and the
    only way to call it is:
    int x = anA.operator int<SomeType>();

    > };


    > 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::eek:perator int;


    Not ill-formed, because it refers to #3.

    > };


    > ------------------------


    > 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.


    I'm still trying to understand the question. But one thing is
    certain:
    int x = anA;
    will, without any further qualifications, invoke #3. And this
    is what I would intuitively expect using A::eek:perator int to
    refer to.

    --
    James Kanze
    James Kanze, Aug 17, 2010
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    0
    Views:
    3,030
  2. Ill-formed program

    , Dec 4, 2008, in forum: C++
    Replies:
    1
    Views:
    403
  3. SG
    Replies:
    5
    Views:
    669
  4. m0shbear
    Replies:
    11
    Views:
    617
    m0shbear
    Jan 30, 2011
  5. K. Frank
    Replies:
    1
    Views:
    335
    K. Frank
    Nov 6, 2011
Loading...

Share This Page