This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 115d. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.
2024-10-26
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.
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.
Rationale (August, 2011):
As given in the preceding note.