"Alf P. Steinbach /Usenet"<alf.p.steinbach+usenet@gmail.com> writes:
* Paul Bibbings, on 20.06.2010 00:15:
I've been working on some code (not mine) that relies on the following
motif leading to a compilation failure, with sensible output, at line
17 (below). The trouble is, with gcc-4.4.3, it *doesn't* fail:
template<typename T>
struct Error { };
template<typename T>
struct A
{
static const int i = Error<T>::TempArgMustBeInt; // line: 7
};
template<>
struct A<int>
{ };
int main()
{
A<int> A_int;
A<char> A_char; // line: 17
}
I'm thinking that it probably should (or, I have no immediate
understanding of why it wouldn't); whoever wrote the original code
(probably some while ago) thought it should; and, Comeau seems to
agree:
Comeau C/C++ 4.3.10.1 (Oct 6 2008 11:28:09) for
ONLINE_EVALUATION_BETA2
Copyright 1988-2008 Comeau Computing. All rights reserved.
MODE:strict errors C++ noC++0x_extensions
"ComeauTest.c", line 7: error: class "Error<char>" has no member
"TempArgMustBeInt"
static const int i = Error<T>::TempArgMustBeInt;
^
detected during instantiation of class "A<T> [with T=char]" at
line 17
// ...
1 error detected in the compilation of "ComeauTest.c".
What does anyone else think?
Sounds like it incorrectly optimizes the "i" away (perhaps it
optimizes A_char away) before checking whether it exists.
I'd try a typedef instead.
I'm assuming that there is some good reason for the restriction (e.g.,
A used as a template template parameter); otherwise just remove the
templating... :-)
The code that I was looking at, and which used the above motif, is from
a paper by McNamara and Smaragdakis on "Static interfaces in C++" -
http://www.cc.gatech.edu/~yannis/static-interfaces/static-interfaces.pdf
(I haven't found the date for this paper, but the latest reference is
Alexandrescu, 2000). The example illustrates static dispatch, along the
lines of:
enum {
SET_HASH, // implement using a hash table
SET_BST, // implement using a binary search tree
SET_LL, // implement using a linked list
SET_NONE // no appropriate implementation
};
template<class T>
struct SetDispatch {
static const bool Hash =
StaticIsA<T, Hashtable>::valid;
static const bool LtC =
StaticIsA<T, LessThanComparable<T> >::valid;
static const bool EqT =
StaticIsA<T, EqualityComparable<T> >::valid;
static const int which = Hash ? SET_HASH
: LtC ? SET_BST
: EqT ? SET_LL
: SET_NONE;
};
template<
class T,
int which = SetDispatch<T>::which
>
struct Set;
template<class T>
struct Set<T, SET_NONE> {
static const int x = Error<T>::
Set_only_works_on_Hashtables_or_LTCs_or_ECs;
Disclaimer: I haven't tried this.