How do I define a template function within a template class outside of the class definition?
IIRC:
template<class T> template <class U>
void Foo<T>::bar() { ...
How to define a templated method of a class template outside of class body
You need two templates: One for the class and one for the function.
Like in:
template<size_t SIZE>
template <typename T>
T SomeClass<SIZE>::someFunction(size_t position) {
return static_cast<T>(position * size); // just do something with type T
}
define function templated class outside of template
Here you go:
template <typename T>
class some{
int hello();
};
//The method needs to be defined outside of the template class declaration and be able to use T defined in the template
template<typename T>
int some<T>::hello(){
T* other = new T;
other->doSomething();
}
How to implement a member function outside of a template class declaration body?
There are a couple of ways to fix this problem:
- Explicit Instantiation
- The Inclusion Model
- The Seperation Model
Explicit Instantiation Works similar to your example of template specialization:
template my_class<size_t>::my_class();
Explicitly instantiates the constructor of my_class<T>
for type size_t.
The Inclusion Model
The code is either written inside the .h file, a very common approach to deal with this problem, or we include the definitions of a template in the header file that declares that template, so:#include "my_file.cpp"
.
The Seperation Model
Use the keyword export
. However, I have almost never used this, as it performs quite slowly.
export template <typename T>
struct C {};
How do I define a template member function outside of a full specialized template class's definition?
§14.7.3 [temp.expl.spec]/p5:
Members of an explicitly specialized class template are defined in the
same manner as members of normal classes, and not using the
template<>
syntax. The same is true when defining a member of an
explicitly specialized member class. However,template<>
is used in
defining a member of an explicitly specialized member class template
that is specialized as a class template.
print
is not a class template. Hence, remove the template <>
:
template <>
struct Foo<int>
{
template <class S>
void print(const int& t, const S& s);
};
template <class S>
void Foo<int>::print(const int& t, const S& s)
{
cout << s << " " << t << endl;
}
Demo.
Note that if you do not explicitly specialize Foo<int>
, but tries to define Foo<int>::print
directly, then you are explicitly specializing a member of a particular implicit instantiation of Foo
, and not defining a member of an explicit specialization. For that, you need template <>
:
template <class T>
struct Foo
{
template <class S>
void print(const T& t, const S& s);
};
template <>
template <class S>
void Foo<int>::print(const int& t, const S& s)
{
cout << s << " " << t << endl;
}
C++ - Define member function outside template-class but in header
14.7/5 says
5 For a given template and a given set of template-arguments,
- an explicit instantiation definition shall appear at most once in a program,
- an explicit specialization shall be defined at most once in a program (according to 3.2), and
- both an explicit instantiation and a declaration of an explicit specialization shall not appear in a program unless the explicit
instantiation follows a declaration of the explicit specialization.An
implementation is not required to diagnose a violation of this rule.
The second bullet applies to your case. The ODR defined in 3.2 says the same thing, albeit in a less distilled form.
Regardless of where and how the non-specialized version of member function is defined, the specialized version definition
template <> bool TestClass<double>::MemberFunction()
{
return true;
};
has to go into a .cpp
file. If kept in the header file, it will produce an ODR violation once the header gets included into more than one translation unit. GCC reliably detect this violation. MSVC seems to be less reliable in that regard. But, as the quote above states, an implementation is not required to diagnose a violation of this rule.
The header file should only contain a non-defining declaration of that specialization
template <> bool TestClass<double>::MemberFunction();
The fact that in MSVC the error appears or disappears depending on such seemingly unrelated factor as how the non-specialized version of the function is defined must be a quirk of MSVC compiler.
After further research, it appears that MSVC implementation is actually broken: its behavior goes beyond what's allowed by the "no diagnostic is required" permission given by the language specification.
The behavior you observed in your experiments in consistent with the following: declaring the primary function template as inline
automatically makes the explicit specialization of that template inline
as well. This is not supposed to be that way. In 14.7.3/14 the language specification says
An explicit specialization of a function template is inline only if it
is declared with the inline specifier or defined as deleted, and
independently of whether its function template is inline.
Template function inside template class
Write this:
template <class T>
template <class U>
void MyClass<T>::foo() { /* ... */ }
Define function outside template class that uses SFINAE?
You were close, you forgot to specify the second template parameter (without the default value):
template <typename ObjectType, typename Dummy>
SampleClass<ObjectType, Dummy>::~SampleClass()
{
// ...
}
Related Topics
Check Traits for All Variadic Template Arguments
Do Class/Struct Members Always Get Created in Memory in the Order They Were Declared
Check Variadic Templates Parameters for Uniqueness
Overloading Operator<<: Cannot Bind Lvalue to 'Std::Basic_Ostream<Char>&&'
How Does One Securely Clear Std::String
Why Does Windows 10 Start Extra Threads in My Program
How to Use Createfile, But Force the Handle into a Std::Ofstream
Stack Overflow Caused by Recursive Function
Why Did Microsoft Abandon Long Double Data Type
What Does the Operation C=A+++B Mean
Casting Between Void * and a Pointer to Member Function
How to 'Cout' the Correct Number of Decimal Places of a Double Value