namespace NS
{
class A
{
public:
template<typename T> void PrintValue(T val);
};
};
}
Namespace definitions don't end with ';'.
template<typename T> void NS::A:
rintValue(T val)
{
std::cout << "Primary Method " << val << std::endl;
}
template<> void NS::A:
rintValue<double>(double dVal)
{
std::cout << "Specialized Method " << dVal << std::endl;
}
int main(int argc, char* argv[])
{
NS::A objA;
objA.PrintValue<int>(5);
objA.PrintValue<double>(10.50);
//These are the errors given by the compiler (gcc 3.4.3)
g++ Test.cpp
Test.cpp:19: error: specialization of `template<class T> void
NS::A:
rintValue(T)' in different namespace
Test.cpp:9: error: from definition of `template<class T> void
NS::A:
rintValue(T)'
Test.cpp:20: confused by earlier errors, bailing out
The specialization for a member function template must be _declared_ in
the same namespace as the class itself (see 14.7.3/2). This means that
if you want to move the _definition_ of the member function template
somewhere else, you have to at least leave a _declaration_ inside the
namespace. In this code you violate this requirement: you are not
declaring the specialization of 'A:
rintValue<double>' inside the NS
namespace first.
In order to make the code compilable, add the declaration for the
specialization to the namespace
namespace NS
{
class A
{
public:
template<typename T> void PrintValue(T val);
};
template<> void A:
rintValue<double>(double dval); // <- added
}
template<typename T> void NS::A:
rintValue(T val)
{
// ...
}
template<> void NS::A:
rintValue<double>(double dVal)
{
// ...
}
In your first example (without namespace) class 'A' was a member of
global namespace. You _defined_ the specialization of
'A:
rintValue<double>' in global namespace as well. In that case the
definition served as declaration at the same time, so the above
requirement was naturally met.
So, alternatively, you can follow the same structure to make the code
with namespace NS compilable. In order to do that you have to move the
function definitions into the namespace
namespace NS
{
class A
{
public:
template<typename T> void PrintValue(T val);
};
template<typename T> void A:
rintValue(T val)
{
// ...
}
template<> void A:
rintValue<double>(double dVal)
{
// ...
}
}
This will also compile.