Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

static member function inside class template specialization

I am struggling to access static member function defined inside class template. In the header file TemplateTest.h I defined the primary class Template as:

#include<iostream>

template<class T, class U>
struct TemplateTest
{
public:
    void static invoke();
    /*{

        std::cout << "Should not be called" << std::endl;

    }*/
};

Then Source File TemplateTester.cpp I put a specialization:

#include "TemplateTest.h"

template<>
struct TemplateTest<int, bool>
{
    static void invoke()
    {
        std::cout << "invoke<int, bool>" << std::endl;   
    }
};

template struct TemplateTest<int, bool>; //instantiate to resolve linker issue

I explicitly instantiated the class with so linker resolves correctly.

In the driver driver.cpp :

include "TemplateTest.h"

int main()
{
    TemplateTest<int, bool>::invoke();
    return 0;
}

When I compile the TemplateTest.cpp with g++ it generates the object file correctly but when I try to link it to the driver class it gives my linker error "undefined reference to `TemplateTest::invoke()"

I went through other related postings like this one but I am not trying access a function template.

Any clue is much appreciated.

like image 656
jazaman Avatar asked Jun 04 '13 04:06

jazaman


People also ask

What happens when there is static member in a template class function?

The static member is declared or defined inside the template< … > class { … } block. If it is declared but not defined, then there must be another declaration which provides the definition of the member.

Can static function be defined inside class?

Static Member Function in C++ The static is a keyword in the C and C++ programming language. We use the static keyword to define the static data member or static member function inside and outside of the class.

Can we call static member function of a class using object of a class in C++?

You cannot have static and nonstatic member functions with the same names and the same number and type of arguments. Like static data members, you may access a static member function f() of a class A without using an object of class A .

Can a static function be template?

The static declaration can be of template argument type or of any defined type. The statement template T K::x defines the static member of class K , while the statement in the main() function assigns a value to the data member for K <int> .


1 Answers

You are right that the object file you create from TemplateTester.cpp will contain a symbol for the specialization you provided. This is the case because any explicit specialization causes the template to be instantiated, and it is doubly the case because you even added an explicit instantiation (which is actually unnecessary).

However, at the time when driver.cpp is compiled, the compiler does not know about the specialization, because you only include TemplateTester.h, and the specialization isn't mentioned there. So the compiler instantiates the template, of course not using the specialized definition, so you get your problem.

The Standard says (Italics by me):

(§14.7.3/6) If a template, a member template or a member of a class template is explicitly specialized then that specialization shall be declared before the first use of that specialization that would cause an implicit instantiation to take place, in every translation unit in which such a use occurs; no diagnostic is required. If the program does not provide a definition for an explicit specialization and either the specialization is used in a way that would cause an implicit instantiation to take place or the member is a virtual member function, the program is ill-formed, no diagnostic required. An implicit instantiation is never generated for an explicit specialization that is declared but not defined. [...]

So you need to make both, the declaration and the definition of the specialization known to the compiler when it works on driver.cpp. The best way of doing this is by adding the entire specialization to TemplateTester.h.

Note, again, that an explicit instantiation is not actually required.

like image 155
jogojapan Avatar answered Oct 21 '22 10:10

jogojapan