1
votes

I have a templated class Converter, and I'd like to do a partial specialization. The tricky part is I'd like to specialize it to MyFoo::Vec where MyFoo again can be specialized as a template parameter. If that sounds confusing, maybe the code itself makes it clearer:

#include <iostream>
#include <vector>

template<class To>
struct Converter {
  Converter(int from, To& to) {
    to = To(from);
  }
};

template<class T>
struct Foo {
  typedef std::vector<T> Vec;
  Vec vec;
};

// Template specialization: Convert from 'From' to 'MyFoo::Vec':                                                                
template<class MyFoo>
struct Converter<typename MyFoo::Vec > { // Error: template parameters not
                                         // used in partial specialization
  Converter(int from, typename MyFoo::Vec& to) {
    to.push_back(typename MyFoo::Vec::value_type(from));
  }
};

int main() {
  Foo<float> myfoo;
  Converter<Foo<float> > converter(2, myfoo.vec);
}

This is just a mini example derived from my actual code. This question is not about how useful such a converter is; I'm just interested in getting the syntax right given that I need such a converter and its specialization.

1

1 Answers

2
votes

It cannot be done directly. Consider that it is impossible to go from the nested type to the enclosing type for two reasons: first, the mapping might not be unique (multiple Foo might have the same nested Vec type) and even if it was the compiler would have to test all existing types (i.e. it cannot infer from the instantiation).

What you want to do can actually be done with SFINAE (untested code, you can read more here):

template <typename T, typename V = void>
struct Converter {};             // Default implementation

template <typename T>
struct Converter<T, T::Vec> {};  // specific if has nested Vec