   template trickery
  Check out this code, which compiles fine:template<typename T> struct Trait {  typedef T Type;};struct Base {  template<typename T> typename Trait<T>::Type get() const;};template<typename T> struct Derived : public Base {  template<> typename Trait<T>::Type get<T>() const { return 0; }};Now contrast to this code, which gives a "; missing before <" error in the struct Derived definition of get():template<typename T> struct Trait {  typedef T Type;};struct Base {  template<typename T> typename Trait<T>::Type get() const;};template<typename T, typename B> struct Derived : public B {  template<> typename Trait<T>::Type get<T>() const { return 0; }};I can sort-of see why -- the compiler doesn't know that I intend to pass a "base" in as type B, so it doesn't know that get<>() is an explicit specialization.How can I work around this, other than adding Base as an explicit base class to the Derived template?   
  I should add that the following also doesn't work:template<typename T> struct Trait {  typedef T Type;};struct BaseBase {  template<typename T> typename Trait<T>::Type get() const;};struct Base : public BaseBase {};template<typename T, typename B> struct Derived : public B, public BaseBase {  template<> typename Trait<T>::Type get<T>() const { return 0; }};The error I get (from MSVC 2005) is: error C2912: explicit specialization; 'const float &Derived<T,B>::get(void) const' is not a specialization of a function template I would argue that it actually IS a specialization of a function template.;  Neither version of your code compiles with gcc 4.1.0.The function declarationtemplate<typename T> typename Trait<T>::Type get() const;won't work, since the return value is not part of the function signature.Did you actually try to call/instantiate this function ?For instance:void foo(){Base bi;int ib = bi.get();Base bf;float fb = bf.get();Derived<int> di;int id = di.get();Derived<float> df;float fd = df.get();}The get() function of the Derived class will work, since there is just one version generated which depends on the template type of the Derived class.The get() function of the Base class will not work, since many versions of this function may be generated and the return value is not used to select one. Either you can explicitly tell the compiler which function to use (i.e. get<int>()) or you can add a parameter which selects the function:template<typename T> typename Trait<T>::Type get(T&) const;;  I don't think it can be done directly, but this works as I think you want. I'm sure that some light sprinkling of Boost might help clean it a bit.#include <iostream>template<typename T> struct Trait {  typedef T Type;};struct Base {    template<typename U> typename Trait<U>::Type get() const    {   return 1;    }};template<typename T, typename B, typename U> struct helper;template<typename T, typename B> struct Derived : public B{    template<typename U> typename Trait<U>::Type get() const    {   return helper<T,B,U>::get(*this);    }    typename Trait<T>::Type get_T() const { return 0; }};template<typename T, typename B, typename U> struct helper{    static typename Trait<U>::Type get( const Derived<T,B>& d )    {   return d.B::template get<U>();    }};template<typename T, typename B> struct helper<T,B,T>{    static typename Trait<T>::Type get( const Derived<T,B>& d )    {   return d.get_T();    }};int main(){    Derived<int,Base> x;    std::cout << x.get<int>() << std::endl;    std::cout << x.get<double>() << std::endl;};  OK, the C++ Standard explicitely [rolleyes] disallow what you want to do in clause 14.7.3-18:Quote:In an explicit specialization declaration for a member of a class template or a member template that appears in namespace scope, the member template and some of its enclosing class templates may remain unspecialized, except that the declaration shall not explicitely specialize a class member template if its enclosing class templates are not explicitely specialized as well. ...I think it works when you specify Base as the base class, because then you are working with a member of Base, which isn't a template.   ;Quote:Original post by nmiNeither version of your code compiles with gcc 4.1.0.The function declarationtemplate<typename T> typename Trait<T>::Type get() const;won't work, since the return value is not part of the function signature.The return type isn't part of the signature, but the template parameters still allow to discriminate. You can explicitely call get<int>() without relying on template argument deduction.   ;Quote:Original post by FrunyThe return type isn't part of the signature, but the template parameters still allow to discriminate. You can explicitely call get<int>() without relying on template argument deduction.That's what I wrote in the last sentence.   ;  Thanks Fruny. That doesn't quite do what I want, though.What I want to do is create structures with metadata to get around the lack of introspection and reflection in C++. The types that I really want to specialize on are the "member names" of the struct. The "helper" route doesn't quite get me there (although I'll cook on it some more).;  Here's a solution to what I actually want to do. I want to declare "members" as type names, and declare structs as aggregates of these members. This allows me to do compile-time reflection to do things like generate visitor for marshalling, etc.// Declare my "member types" (this can be macro-ized)template<typename T> struct Traits;struct foo;template<> struct Traits<foo> {  typedef unsigned short Type;};struct bar;template<> struct Traits<bar> {  typedef float Type;};// Declare helpers in the systemtemplate<typename N> struct Member {  typename Traits<N>::Type _memb;};struct Base {};template<typename N, typename B = Base> struct Instance : B, Member<N> {  template<typename T> typename Traits<T>::Type const & get() const {    return Member<T>::_memb;  }  template<typename T> void set(typename Traits<T>::Type const & t) {    Member<T>::_memb = t;  }};// Declare an actual structure used by a userstruct X :  public Instance<foo, Instance<bar> >{};int main(int argc, char* argv[]){  X x;  x.set<foo>(10):  x.set<bar>(20);  x.get<foo>();  x.get<bar>();  return 0;}So, I'm now happy again.   ;Quote:Original post by hplus0603Here's a solution to what I actually want to do. I want to declare "members" as type names, and declare structs as aggregates of these members.Sounds like you want a Boost.Fusion map, which was formally accepted into Boost in May and will be included with Boost in 1.34. For now, you can grab it here. Documentation is in the libs directory.As an example, you can accomplish what you want in Boost.Fusion as:#include <boost/fusion/sequence/container/map.hpp>struct foo;struct bar;int main(){  using namespace ::boost::fusion;  map< pair< foo, unsigned short >, pair< bar, float > > your_map;  at< foo >( your_map ) = 10;  at< bar >( your_map ) = 20;}