$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
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