Title
Conversion operator template syntax
Status
nad
Section
11.4.8.3 [class.conv.fct]
Submitter
Daveed Vandevoorde

Created on 2002-12-18.00:00:00 last changed 153 months ago

Messages

Date: 2011-08-15.00:00:00

Rationale (August, 2011):

As given in the preceding note.

Date: 2010-06-15.00:00:00

Note (June, 2010):

It has been suggested that template aliases effectively address this issue. In particular, an identity alias like

    template<typename T> using id = T;

provides the necessary syntactic sugar to be able to specify types with trailing declarator elements as a conversion-type-id. For example, the two cases discussed above could be written as:

    struct S {
        template<typename T, int N>
          operator id<T[N]>&();
        template<typename T, typename U>
          operator id<T (U::*)()>() const;
    };

This issue should thus be closed as now NAD.

Date: 2022-11-20.07:54:16

A posting in comp.lang.c++.moderated prompted me to try the following code:

  struct S {
    template<typename T, int N> (&operator T())[N];
  };

The goal is to have a (deducible) conversion operator template to a reference-to-array type.

This is accepted by several front ends (g++, EDG), but I now believe that 11.4.8.3 [class.conv.fct] paragraph 1 actually prohibits this. The issue here is that we do in fact specify (part of) a return type.

OTOH, I think it is legitimate to expect that this is expressible in the language (preferably not using the syntax above ;-). Maybe we should extend the syntax to allow the following alternative?

  struct S {
    template<typename T, int N> operator (T(&)[N])();
  };

Eric Niebler: If the syntax is extended to support this, similar constructs should also be considered. For instance, I can't for the life of me figure out how to write a conversion member function template to return a member function pointer. It could be useful if you were defining a null_t type. This is probably due to my own ignorance, but getting the syntax right is tricky.

Eg.

  struct null_t {
    // null object pointer. works.
    template<typename T> operator T*() const { return 0; }
    // null member pointer. works.
    template<typename T,typename U> operator T U::*() const { return 0; }
    // null member fn ptr.  doesn't work (with Comeau online).  my error?
    template<typename T,typename U> operator T (U::*)()() const { return 0; }
  };

Martin Sebor: Intriguing question. I have no idea how to do it in a single declaration but splitting it up into two steps seems to work:

  struct null_t {
    template <class T, class U>
    struct ptr_mem_fun_t {
      typedef T (U::*type)();
    };

    template <class T, class U>
    operator typename ptr_mem_fun_t<T, U>::type () const {
      return 0;
    }
  };

Note: In the April 2003 meeting, the core working group noticed that the above doesn't actually work.

History
Date User Action Args
2011-09-06 00:00:00adminsetmessages: + msg3580
2011-09-06 00:00:00adminsetstatus: review -> nad
2010-08-23 00:00:00adminsetmessages: + msg2829
2010-08-23 00:00:00adminsetstatus: open -> review
2002-12-18 00:00:00admincreate