terry
template <
int W0=0, int W1=0, int W2=0, int W3=0, int W4=0,
int W5=0, int W6=0, int W7=0, int W8=0, int W9=0
>
class IntArgs {
public:
template <int N> struct Arg { };
template <> struct Arg<0> { static const int value = W0; };
template <> struct Arg<1> { static const int value = W1; };
template <> struct Arg<2> { static const int value = W2; };
template <> struct Arg<3> { static const int value = W3; };
template <> struct Arg<4> { static const int value = W4; };
template <> struct Arg<5> { static const int value = W5; };
template <> struct Arg<6> { static const int value = W6; };
template <> struct Arg<7> { static const int value = W7; };
template <> struct Arg<8> { static const int value = W8; };
template <> struct Arg<9> { static const int value = W9; };
template <int N>
struct Offset {
static const int value = Arg<N-1>::value + Offset<N-1>::value;
}; // Offset
template <> struct Offset<0> { static const int value = 0; };
}; // IntArgs
#include <iostream>
#include <iomanip>
#include <typeinfo>
using namespace std;
int main() {
typedef IntArgs<41, 23, 17, 99> MyInts;
cout << typeid(MyInts).name() << endl;
cout << "MyInts::Arg<2>::value=" << MyInts::Arg<2>::value << endl;
cout << "MyInts::Offset<2>::value=" << MyInts::Offset<2>::value << endl;
return 0;
} // main
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
standard does not.
I think some compilers (Comeau?) even have a flag to mimic
this MSVC 'compatibility', against the standard.
not to mention that people even filed GCC bugs related to the error
'explicit specialization in non-namespace scope':
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34726
read 14.7.3 - Explicit specialization [temp.expl.spec]
especially 14.7.3.2, 14.7.3.17, 14.7.3.18.
14.7.3.2:
-2- An explicit specialization shall be declared in the namespace of
which the template is a member, or, for member templates, in the
namespace of which the enclosing class or enclosing class template is
a member. An explicit specialization of a member function, member
class or static data member of a class template shall be declared in
the namespace of which the class template is a member.
please look at example below, you can see how I moved
the explicit specialization at namespace scope:
// -----------------------------------------
/*
* inner_specialized.cpp
*
* Created on: Nov 10, 2008
* Author: gil
*/
#include <iostream>
struct Outer {
template< int I > struct Inner {
static const int value = Inner< I - 1 >::value;
};
/*
* gcc conforms to standard;
* standard (14.7.3.2) would not allow you to
* explicitly specialize Inner here,
* (but will accept a partial specialization)
*/
/*
template< > struct Inner< 0 > {
static const int value = 0;
};
*/
};
template< >
struct Outer::Inner< 0 > {
static const int value = 0;
};
using namespace std;
int main( ) {
cout << Outer::Inner< 10 >::value << endl;
return EXIT_SUCCESS;
}
// -----------------------------------------
in your example it's easier to add a bogus template parameter to inner
template members and only specialize them partially at class scope.
so standard allows this:
// ---------------------------------------------------
template <
int W0=0, int W1=0, int W2=0, int W3=0, int W4=0,
int W5=0, int W6=0, int W7=0, int W8=0, int W9=0
>
class IntArgs {
public:
template < int N, typename T = void > struct Arg { };
// note the partial vs explicit specialization
template <typename T> struct Arg<0, T> { static const int value =
W0; };
template <typename T> struct Arg<1, T> { static const int value =
W1; };
template <typename T> struct Arg<2, T> { static const int value =
W2; };
template <typename T> struct Arg<3, T> { static const int value =
W3; };
template <typename T> struct Arg<4, T> { static const int value =
W4; };
template <typename T> struct Arg<5, T> { static const int value =
W5; };
template <typename T> struct Arg<6, T> { static const int value =
W6; };
template <typename T> struct Arg<7, T> { static const int value =
W7; };
template <typename T> struct Arg<8, T> { static const int value =
W8; };
template <typename T> struct Arg<9, T> { static const int value =
W9; };
template <int N, typename T = void>
struct Offset {
static const int value = Arg<N-1, T>::value + Offset<N-1,
T>::value;
}; // Offset
// again, using partial specialization at class scope
template <typename T> struct Offset<0, T> { static const int value
= 0; };
}; // IntArgs
// ----------------------------------------------------
with above modifications, compiled with g++ (GCC) 4.1.1,
your test programs displays:
7IntArgsILi41ELi23ELi17ELi99ELi0ELi0ELi0ELi0ELi0ELi0EE
MyInts::Arg<2>::value=17
MyInts::Offset<2>::value=64
cheers,
gil
terry
"Terry G" <tjgo...@netins.net> wrote in message
news:gf9805$8th$1...@news.netins.net...
> The following program compiles and works with Visual C++ but not with G++
> 4.3.0 or G++ 4.4.0.
> GCC complains that I'm using "explicit specialization in non-namespace
> scope".
> Should this work?
>
> terry
>
> template <
> int W0=0, int W1=0, int W2=0, int W3=0, int W4=0,
> int W5=0, int W6=0, int W7=0, int W8=0, int W9=0
>>
> class IntArgs {
> public:
>
> template <int N> struct Arg { };
becomes
template <int N, int Dummy=0> struct Arg { };
>
> template <> struct Arg<0> { static const int value = W0; };
becomes
template <int Dummy> struct Arg<0, Dummy> { static const int value =
W0; };
...