Here is some code which does not compile.
namespace ns
{
class foo
{
template <typename T> int bar (T *);
};
}
template <typename T>
int ns :: foo :: bar (T*) // this is OK
{
return 0;
}
template <>
int ns :: foo :: bar <int> (int *) // this is an error
{
return 1;
}
The error is: "specialisation of ‘template int ns::foo::bar(T*)’ in different namespace [-fpermissive] from definition of ‘template int ns::foo::bar(T*)"
Here is a version which does compile:
namespace ns
{
class foo
{
template <typename T> int bar (T *);
};
}
template <typename T>
int ns :: foo :: bar (T*)
{
return 0;
}
namespace ns
{
template <>
int foo :: bar <int> (int *)
{
return 1;
}
}
Why does the second definition have to be in a namespace ns {}
block when the first one is quite happily defined with a qualified name? Is it just an oversight in the language design or is there a reason for this?
C++ templates make an algorithm independent of the type of data employed. The entities of variable, function, struct, and class can have templates, which involve declaration and definition. Creating a template also involves specialization, which is when a generic type takes an actual type.
Templates in c++ is defined as a blueprint or formula for creating a generic class or a function. To simply put, you can create a single function or single class to work with different data types using templates. C++ template is also known as generic functions or classes which is a very powerful feature in C++.
To instantiate a template class explicitly, follow the template keyword by a declaration (not definition) for the class, with the class identifier followed by the template arguments. template class Array<char>; template class String<19>; When you explicitly instantiate a class, all of its members are also instantiated.
There are three kinds of templates: function templates, class templates and, since C++14, variable templates. Since C++11, templates may be either variadic or non-variadic; in earlier versions of C++ they are always non-variadic.
The problem here is not the definition, but the declaration. You cannot inject a declaration in a namespace from a different namespace, so the specialization must be declared in the appropriate namespace before it can be defined in any enclosing namespace.
The definition of the base template can be done in the outer namespace because it has already been declared, so the code in the outer namespace provides a definition but does not inject any declaration into the namespace.
Try:
namespace ns {
class foo
{
template <typename T> int bar (T *);
};
template <>
int foo::bar<int>(int*); // declaration
}
template <typename T>
int ns :: foo :: bar (T*) {
return 0;
}
template <>
int ns :: foo :: bar <int> (int *) {
return 1;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With