Outline definition of template functions

Consider this (minimized) example:

template <typename Descriptor> class hash_table { public: typedef int value_type; template <typename Argument, int Callback (value_type *, Argument)> void traverse (Argument); template <int Callback (value_type *)> void traverse_void (); }; 

I defined a class template that has template member functions with non-type parameters. Note that Callback depends on the value_type typedef. Now I want to define the functions themselves:

 template <typename Descriptor> template <typename Argument, int Callback (typename hash_table <Descriptor>::value_type *, Argument)> void hash_table <Descriptor>::traverse (Argument) {} template <typename Descriptor> template <int Callback (typename hash_table <Descriptor>::value_type *)> void hash_table <Descriptor>::traverse_void () {} 

I get inconsistent errors from compilers. The result does not depend on the parameters, indicating the version of the C ++ standard (i.e. the same for C ++ 98, C ++ 11 and C ++ 14), but it depends on the compiler.

GCC 6.0.0 (a recent trunk, as well as several other versions) accepts this code.

Clang 3.7.0 (last line) gives the following error:

 test.cc:18:31: error: out-of-line definition of 'traverse_void' does not match any declaration in 'hash_table<Descriptor>' void hash_table <Descriptor>::traverse_void() {} ^~~~~~~~~~~~~ 1 error generated. 

EDG (Intel C ++ Compiler v. 15.0.3) gives two errors:

 test.cc(15): error: declaration is incompatible with function template "void hash_table<Descriptor>::traverse<Argument,Callback>(Argument)" (declared at line 7) void hash_table <Descriptor>::traverse (Argument) {} ^ test.cc(19): error: declaration is incompatible with function template "void hash_table<Descriptor>::traverse_void<Callback>()" (declared at line 10) void hash_table <Descriptor>::traverse_void () {} ^ compilation aborted for test.cc (code 2) 

What is the expected behavior (according to the standard)? If the code is incorrect, how can I fix function definitions?

+7
c ++ language-lawyer templates member-functions
source share
1 answer

Your code looks good to me, I see no reason to compile it. Probably a bug in compilers that don't allow it. However, since [temp.param]:

A non-standard template parameter of the type "array from T " or "return of the function T " is configured as the type "pointer to T " or "pointer to the function of return T ", respectively.

You can simply switch Callback yourself to be a function pointer. The behavior would be the same in every way, with the added benefit that this code also compiles to clang.

+1
source share

All Articles