tags:

views:

1058

answers:

4

Having a brain fart... Is it possible to make something like this work?

template<int a> struct Foo
{
    template<int b> struct Bar;
};

template<int a> struct Foo<a>::Bar<1> //Trying to specialize Bar
{
};

I don't have to do this, but it will allow me to nicely hide some implementation details from namespace scope.

Suggestions appreciated!

P.S.: I forgot to mention that explicitly specializing for Bar within Foo's scope isn't supported by the language. AFAICS, anyway.

+2  A: 

According to these posts:

http://www.cpptalk.net/template-member-function-specialization-vt11666.html

you cannot specialize template members of a template class without specializing the outside class. They do not cite verse and chapter. My copy of "The C++ Programming Language" does not reveal anything immediately, and my copy of the standard is at home (my backup copy, better known here as "Chris" is not around either :-)

coryan
Disappointing.Thanks for the reference, though!
LDynCC
ISO14882:1998 Section 14.7.3, paragraph 16 is the one that describes this situation.
greyfade
A: 

You can't do that. I've tried many variations. This, however, compiles in GCC 4.1:

template<int a> struct Foo
{
    template<int b> struct Bar;
    template<1> struct Bar;
};

Edit (after reviewing the standard): If a is given, however, you can do this:

template <> template <> Foo<1> Bar<1>;

But not if Foo is not first specialized.

greyfade
+4  A: 

Yes, you can. But you'll need to change the call structure, but just a little bit.

Specifically, use the strategy pattern to restructure the implementation of the member function as a class (which IS allowed to be specialized).

This is permitted as long as the strategy class is not nested (and hence not dependent on the unspecialized template type).

e.g. (this probably isn't syntactically correct, but the idea should be clear)

template <class T>
class OuterThingThatIsNotSpecialized
{
  template <class U>
  void memberWeWantToSpecialize(const U& someObj_)
  {
    SpecializedStrategy<U>::doStuff(someObj_);
  }
};

template <class U>
struct SpecializedStrategy;

template <>
SpecializedStrategy<int>
{
  void doStuff(const int&)
  {
    // int impl
  } 
};

template <>
SpecializedStrategy<SomeOtherType>
{
  void doStuff(const SomeOtherType&)
  {
    // SOT impl
  } 
};

This is incredibly useful because calls to OuterThingThatIsNotSpecialized for types where no implementation exists will simply fail to compile.

PS. You can even use this strategy to partially specialize template functions, something that is an otherwise C++ impossibility.

note that he has a member template class, and not a member template function. the thing is more complicated for a member template class. because for example friendship is not granted anymore.
Johannes Schaub - litb
A: 

Clause 18, Section 14.7.3 of the 1998 standard (ISO14882:1998) says explicit specialisation of (the inner) template member classes in not allowed when the (outer) template class is not explicitly specialised.

Hossein HAERI