Re: Specialising template member functions with templatized parameters - legal?
Karthick wrote:
Is the following snippet legal C++? I'm assuming I'm doing something
wrong, but can't figure out what...
template <int SIZE>
struct othersize;
template <>
struct othersize <0>
{
typedef int type;
};
...
class B {
template <int SIZE>
void to(typename othersize<SIZE>::type te);
};
// >>> Specialised implementation of to
template<>
void B::to<0>(othersize<0>::type){ }
// <<<
Compiling the code with VC++ (7.1) with .NET (1.1) gives me a compile
error:
error C2910: 'to' : cannot be explicitly specialized
for the specialised implementation of to<0>
VC appears to be correct in rejecting the explict specialization of
class B's "to" method. The C++ Standard lists seven kinds of templates
that can be explicitly specialized [?14.7.3/1]. And while a member
function template of a class template is included on the list, a member
function template of a class is not. Therefore the explicit
instantiation syntax cannot be applied to the B::to member function
template.
One solution would be to declare B a class template. Although without
any other reason for B to be a class template, this workaround seems
less than ideal.
A much better solution would be to overload the "to" class method
instead of specializing it. In fact, the effect of specializing a
function template is usually not the result that the progammer
intended. A programmer often specializes a function template as a way
to ensure that the specialization will be called when the parameter
type matches the argument type. In other words, whenever "to" is called
with an "othersize<0>" type parameter the program is to execute the
specialization.
In reality, defining a function specialization for "B::to" has no such
effect. There is no guarantee that the specialization will execute when
B::to is called with an othersize<0> parameter. A B::to function
overload - on the other hand - would provide such a guarantee. In other
words, because the compiler does not consider function specializations
when resolving an overloaded function call, there is always the
possibility that some other overload of the function (instead of the
specialization) will be the function that actually executes.
To overload B's "to" method simply declare it as an ordinary member
function:
class B
{
public:
template <int SIZE>
void to(typename othersize<SIZE>::type te);
void to( othersize<0> te );
...
};
Greg
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]