dimanche 11 mai 2014

c ++ - compilateur dit méthode dans la classe de modèle n'est pas défini à moins que je me fais virtuel ? -Débordement de pile



This question already has an answer here:




Please read this first:


Storing C++ template function definitions in a .CPP file


This is what I am attemptng here.


I used the first method from this site to define a template class in a cpp file:


http://www.codeproject.com/Articles/48575/How-to-define-a-template-class-in-a-h-file-and-imp


It looks like this:


b.h :


#ifndef B_H_
#define B_H_
class B
{
public:
B();
};
#endif

a.h :


#ifndef A_H_
#define A_H_
template<class T>
class A
{
public:
A();
int get();

private:
int val;
};
#endif

a.cpp


#include "a.h"

template <class T>
A<T>::A()
{
}

template <class T>
int A<T>::get()
{
return 42;
}

// No need to call this TemporaryFunction() function,
// it's just to avoid link error.
void TemporaryFunction ()
{
TestTemp<B> TempObj;
}

main.cpp


#include "a.h"
int main(int argc, char** argv){
A<B> ab;
ab.get();
}

I have to change get to virtual or I get:



undefined reference to `A::get()'



I don't understand this. This is just a sample of the real code (that is too large). If it does not reproduce, I will provide more details tomorrow.


gcc version 4.8.1 (Ubuntu/Linaro 4.8.1-10ubuntu9)




Template members are either explicitly instantiated or instantiated on demand. You are not explicitly instantiating the template, but rather causing the implicit instantiation of the type and the constructor by means of the local variable. Since you don't use A<B>::get() that function will not be instantiated by the compiler.


If the function is marked as virtual, then it is odr-used just by means of instantiating the object (hint: the address of each virtual function, or a similar piece of information, needs to be stored in the vtable).


That being said, and without reading the article in question, this approach is wrong. You don't need to create the function and cause the instantiation of each member function, but rather use explicit instantiation of the template.


template class A<B>;   // Explicit instantiation



This question already has an answer here:




Please read this first:


Storing C++ template function definitions in a .CPP file


This is what I am attemptng here.


I used the first method from this site to define a template class in a cpp file:


http://www.codeproject.com/Articles/48575/How-to-define-a-template-class-in-a-h-file-and-imp


It looks like this:


b.h :


#ifndef B_H_
#define B_H_
class B
{
public:
B();
};
#endif

a.h :


#ifndef A_H_
#define A_H_
template<class T>
class A
{
public:
A();
int get();

private:
int val;
};
#endif

a.cpp


#include "a.h"

template <class T>
A<T>::A()
{
}

template <class T>
int A<T>::get()
{
return 42;
}

// No need to call this TemporaryFunction() function,
// it's just to avoid link error.
void TemporaryFunction ()
{
TestTemp<B> TempObj;
}

main.cpp


#include "a.h"
int main(int argc, char** argv){
A<B> ab;
ab.get();
}

I have to change get to virtual or I get:



undefined reference to `A::get()'



I don't understand this. This is just a sample of the real code (that is too large). If it does not reproduce, I will provide more details tomorrow.


gcc version 4.8.1 (Ubuntu/Linaro 4.8.1-10ubuntu9)



Template members are either explicitly instantiated or instantiated on demand. You are not explicitly instantiating the template, but rather causing the implicit instantiation of the type and the constructor by means of the local variable. Since you don't use A<B>::get() that function will not be instantiated by the compiler.


If the function is marked as virtual, then it is odr-used just by means of instantiating the object (hint: the address of each virtual function, or a similar piece of information, needs to be stored in the vtable).


That being said, and without reading the article in question, this approach is wrong. You don't need to create the function and cause the instantiation of each member function, but rather use explicit instantiation of the template.


template class A<B>;   // Explicit instantiation

0 commentaires:

Enregistrer un commentaire