Re: Is this valid code?
On 9/6/07 10:02 AM, in article
1189084995.544996.241800@k79g2000hse.googlegroups.com, "Nicola Musatti"
<nicola.musatti@gmail.com> wrote:
The following program is supposed to use SFINAE to identify whether a
specific template specialization is defined:
In other words, the program is attempting to test whether a particular
template specialization is a complete type - at the point in the translation
unit where the test is applied.
#include <iostream>
class A {};
class B {};
template <typename T> class X;
template <> class X<A> {};
template <template <typename> class C, typename T> class is_defined {
typedef char no;
typedef char (&yes)[2];
static no fn( ... );
static yes fn(C<T>);
static C<T> const& make();
public:
static const bool value = sizeof( fn( make() ) ) == sizeof(yes);
};
int main() {
std::cout << is_defined<X, A>::value << '\n';
std::cout << is_defined<X, B>::value << '\n';
}
Is this valid? Am I invoking undefined behaviour? I'm asking because
just about every compiler I have access to treats it differently.
Comeau 4.3.8 Beta complains that the return value of make() cannot be
converted to X<B>, because it is incomplete;
The program is valid - it manages to avoid instantiating X<B> (which would
be a compile-time error) but only because the sizeof() expression does not
evaluate its argument. But otherwise the program does not accomplish
anything useful - nor could it ever be made to work as intended. Logically,
it is not possible to write a type trait class (like "is_defined" above) to
test a type for "completeness" - because the completeness of a type is not
an inherent property of that type - nor is it even likely to be a constant.
After all, a type may be incomplete at one point in a source file and be
completed later on in that same source file.
So even if is_defined worked, the fact that the static bool constant,
is_defined<>::value, can be initialized to both "true" and "false"- would
run afoul of C++'s One Definition Rule - as well as other requirements in
the Standard that do not permit the completeness of a type to affect the
semantics of the program.
Moreover, there is nothing useful that a program could do with a working
"is_defined" test in the first place. There are only two possibilities to
consider: either a program uses a particular type only in ways that do not
require that type to be complete (so whether the type is actually complete
or not is utterly irrelevant to the program's behavior); or, the program
uses a particular type in a way that requires a complete type - and in which
case the programmer (to prevent a compile-time error) has no choice but to
make sure that the type in question is complete.
Greg
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]