|
Boost : |
From: Paul Mensonides (pmenso57_at_[hidden])
Date: 2002-04-25 18:51:50
> > struct Y {
> > template<class> class nested { }; // i.e. nested is a template, not a
type
> > };
>
> I believe Comeau C++ is right here. A type is a different "meta-type"
> than a template, and the language really differentiates those.
> (Note the "typename" and "template" keywords required to help
> the compiler with that in template definitions.)
>
> Similar for the reverse.
That was not my point exactly. Obviously, a template is not a type and
therefore should not match. In fact, the relative part of the standard says
(paraphrased) use of a given member that is not a type when a type is required
should cause template type deduction to fail. The problem with Comeau C++ is
that it is not 'failing' template type deduction (which it should) nor is it
emitting a normal error. Instead, it is emitting a compiler assertion failure
in 'template.c' at line <such and such>. Take the following example:
----- sample 1 -----
#include <iostream>
typedef char small_t;
typedef char (& large_t)[256];
template<class T> class has_nested_type {
private:
template<class U> static small_t check(typename U::type*);
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_nested_type<T>::value;
struct X { // 'type' is a template
template<class> struct type { };
};
int main(int argc, char* argv[]) {
std::cout << has_nested_type<X>::value << &std::endl;
return 0;
}
----- output -----
"test2.cpp", line 49: internal error: assertion failed at: "templates.c", line
5623
static const bool value = sizeof(check<T>(0)) == sizeof(small_t);
^
----- remarks -----
According to 14.8.2/2 (bullet 3, sub-bullet 3), which says type deduction should
fail...
"Attempting to use a type in the qualifier portion of a qualified name that
names a type when that type does not contain the specified member, or if the
specified member is not a type where a type is required."
... in the case of 'X', 'type' is *not* a type where a type is required.
Therefore, the function should have failed template type deduction and not been
added to the candidate set.
----- sample 2 -----
#include <iostream>
typedef char small_t;
typedef char (& large_t)[256];
template<class T> class has_template_type {
private:
template<class U> static small_t check(typename U::template type<int>*);
template<class U> static small_t check(typename U::template type<int,
int>*);
template<class U> static small_t check(typename U::template type<int, int,
int>*);
// etc.
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_template_type<T>::value;
struct Y { // 'type' is *not* a template
struct type { };
};
int main(int argc, char* argv[]) {
std::cout << has_template_type<Y>::value << &std::endl;
return 0;
}
----- output -----
"test2.cpp", line 51: error: more than one instance of overloaded function
"has_template_type<T>::check [with T=Y]" matches the argument list:
function template
"has_template_type<T>::check(U::type<int> *) [with T=Y]"
function template "has_template_type<T>::check(U::type<int, int>
*) [with T=Y]"
function template "has_template_type<T>::check(U::type<int, int,
int> *) [with T=Y]"
argument types are: (int)
static const bool value = sizeof(check<T>(0)) == sizeof(small_t);
^
detected during instantiation of class
"has_template_type<T> [with T=Y]" at line 67
----- remarks -----
There doesn't seem to be anything in the 14.8.2 list that directly refers to
this, however the 'error' that Comeau C++ gives in clearly erroneous. None of
the said functions match the argument list. Comeau seems to be ignoring the
explicit 'template' keyword in the function declarations.
Paul Mensonides
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk