Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Out-of-class definition of function of specialized inner class template?

Please consider the following ill-formed program:

struct S {
    template<class T> struct J { };
};

template<>
struct S::J<void> {
    void f();
};

template<>
void S::J<void>::f() {} // ERROR

$ clang++ -std=c++11 test.cpp 
no function template matches function template specialization 'f'

$ g++ -std=c++11 test.cpp
template-id ‘f<>’ for ‘void S::J<void>::f()’ does not match any template declaration

Why doesn't the definition of f compile? How do I define the function f correctly in the above?

like image 430
Andrew Tomazos Avatar asked Feb 11 '15 13:02

Andrew Tomazos


People also ask

What is function template specialization?

The act of creating a new definition of a function, class, or member of a class from a template declaration and one or more template arguments is called template instantiation. The definition created from a template instantiation is called a specialization.

What is class template?

A class template provides a specification for generating classes based on parameters. Class templates are generally used to implement containers. A class template is instantiated by passing a given set of types to it as template arguments.

Which keyword can be used to create a template?

5. Which keyword is used for the template? Explanation: C++ uses template reserved keyword for defining templates.


1 Answers

The clang error is very helpful here:

no function template matches function template specialization 'f'
// ^^^^^^^^^^^^^^^^^

The syntax you're using is for a function template. But f isn't a function template, it's just a function. To define it, we don't need the template keyword:

void S::J<void>::f() {}

At this point, S::J<void> is just another class, so this is no different than your standard:

void Class::method() { }

You'd only need template if you were defining a member function of a template, for instance:

template <typename T>
void S::J<T>::g() { }

or a member function template:

template <typename T>
void S::J<void>::h<T>() { }
like image 88
Barry Avatar answered Oct 01 '22 17:10

Barry