c++ - Partial specialization of double-templated method fails -


there template class list.

template <typename point> class list {       public:           template <const unsigned short n>           void load ( const char *file);           ... };  template <typename point> template <const unsigned short n> void list <point>::load ( const char *file) } 

how specialize method load n=2? code not valid...

template <typename point> void list <point> <2>::load ( const char *file) { } 

and code not work.

template <typename point> void list <point> ::load <2> ( const char *file ) {  }  error 3 error c2768: 'list<point>::load' : illegal use of explicit template arguments 66.  error 5 error c2244: 'list<point>::load' : unable match function definition existing declaration 66 

compiler g++:

template <typename point> template <> void list <point> ::load <2> ( const char *file ) { }  error: explicit specialization in non-namespace scope `class list<>' error: enclosing class templates not explicitly specialized error: default arguments permitted function parameters error: `load' not function template error: invalid function declaration 

it turns out there's provision in c++ spec explicitly disallows specializing template class or function nested inside of template class unless explicitly specialize outer template well. visual studio doesn't enforce rule, hence confusion previous example, g++ does.

if want specialize template, options either specialize outer template or somehow fake behavior of specialization having method dispatch 1 of 2 different implementations based on template parameter. neither of these satisfying, know, unfortunately language designed weirdly in template corners. :-(

one way can emulate behavior of explicit specialization use technique called tag dispatching. idea we'll make simple struct looks this:

template <unsigned short n> struct box {}; 

this type empty. it's not meant used directly, rather way of embedding integer type system. in particular, box<3> not same type box<4>, etc.

next, in list class, define 2 functions this, preferably marked private:

template <unsigned short n>     void doload(const char* file, box<n>); void doload(const char* file, box<2>); 

these 2 functions overloads of 1 another, distinguishable final parameter, either box<n> in template case or box<2> in non-template case. note parameters don't have names. arbitrary decision, since we're not planning on reading parameters, don't need them. intuition behind these functions first function "catch-all" implementation work n except 2. second version contain implementation of loading case n == 2.

finally, implement load follows:

template <typename point>     template <unsigned short n> void list<point>::load(const char* file) {     doload(file, box<n>()); } 

how work? function takes in parameter, , calls doload forwarding parameter first argument , passing temporary box<n> second argument. if n not two, call template version of doload, catch-all handler. if, on other hand, n two, call non-template version of doload, because non-template functions have priority on template functions during overload resolution.

in short, implementation of load becomes trampoline forward correct of 2 implementations. can put logic in appropriate doload function behavior want.

hope helps!


Comments

Popular posts from this blog

python - Scipy curvefit RuntimeError:Optimal parameters not found: Number of calls to function has reached maxfev = 1000 -

c# - How to add a new treeview at the selected node? -

java - netbeans "Please wait - classpath scanning in progress..." -