From: Paul Mensonides (pmenso57_at_[hidden])
Date: 2002-04-23 17:27:18


> Please see ISO C++ core issue 339 at
> http://wwwold.dkuug.dk/JTC1/SC22/WG21/docs/cwg_active.html#339
>
> I'm very interested in real-world examples for the case mentioned
> in the issue. (Note the template instantiation in the return type
> of the function, not within the definition of some integral
> const member, as is the case in the examples shown on this list so
> far.)
>
> Jens Maurer

I looked at this issue, and I don't understand what name mangling has to with
this. The result of sizeof is an integral constant of type std::size_t--always.
So why would it matter how you came up with that unsigned value as far as name
mangling is concerned. I.e. from the example A<1U> is the same type as
A<sizeof(char)>. Maybe I'm missing something.

On a similar topic, I think the 'rules' for when type deduction can fail are
ridiculous. They could easily be rewritten to say something like: template
type deduction fails if argument replacement results in something nonsensical.
<-- translated into standardese, of course -- And then follow it with a list of
things that *are* allowed that normally aren't such as adding 'const' to a type
that is already const. If we could do that, then we could implement stuff like
'has_default_ctor':

template<class T> struct has_default_ctor {
    private:
        template<unsigned> struct helper;
        template<class U> static small_t check( helper<sizeof(new U)>* );
        template<class U> static large_t check( ... );
    public:
        static const bool value = sizeof(check<T>(0)) == sizeof(small_t);
};

template<class T> const bool has_default_ctor<T>::value;

struct X {
    X(int); // no default ctor
};

int main() {
    std::cout << has_default_ctor<X>::value << &std::endl;
    return 0;
}

Given the 'rewritten' rules of template type deduction failure, the 'helper<>'
overload would not be added to the candidate set because 'new U' is not a valid
expression. The standard is very unclear about what it means to 'instantiate' a
function template 'declaration'. According to the current rules, the
declaration is 'instantiated' prior to being added to the candidate set. The
only other example that I know of that deals with declaration instantiation is
class member functions:

template<class T> struct Z {
    void set(void (T::*)(void)) { };
};

This is a compile-time error if Z is instantiated with a non-class type--because
of the instantiation of the declaration of the function 'set'--even if you never
call it at all.

Apparently, because of some discussions about this that I had on comp.std.c++,
the compiler only needs to 'partially' instantiate the declaration in order to
produce a candidate function. <-- that is *not* mentioned in the standard
anywhere. Basically, this whole area needs to be significantly cleaned up.

Paul Mensonides