How to Define a Template Function Within a Template Class Outside of the Class Definition

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



Leave a reply



Submit