0

In general, templates are implemented in the header files (as many answers in Stack Overflow point out) so the code template is available to the compiler when it needs it to create a new instance of the class/function. However, in my case, some of the methods in my template class can be used only for a certain type, so my class looks like:

Class header

#ifndef LEC_H
#define LEC_H

#include <iostream>

template <typename T>
class LEC
{
public:
  LEC()
  {
  }

  void func() const;

  void func2() const
  {
    std::cout << "Func 2" << std::endl;
  }
};

#endif  // LEC_H

Class cpp

#include "lec.h"

template <typename T>
void LEC<T>::func() const
{
  std::cout << "Func: " << typeid(T).name() << std::endl;
}

template class LEC<float>;
template class LEC<double>;

The last two lines of the cpp file allow me to use func() because I explicitly instantiate this class template for these two types. When I use this class template in a program I can use any type as long as I do not call func():

#include "lec.h"

int main()
{
  LEC<float> a;
  LEC<double> b;
  a.func2();
  a.func();
  b.func2();
  b.func();
  LEC<char> c;
  c.func2();
  return 0;
}

But, since the code is not available for the compiler to intsantiate func() for a LEC class with type char, I cannot do c.func() or I will get a compiler error:

undefined reference to `LEC::func() const'

This is a simplification of my real code. However, in my code, when I do LEC<char> c to create an instance of the class I get the error, without calling any methods, only by constructing the class.

  • Any idea on how to find out why this, apparently not used method, has to be linked anyways?
  • Is there a way so the compiler (in my case I am using clang++: clang version 6.0.0-1ubuntu2) points out where is this method used within the code?
  • Otherwise, can somebody explain why this (not having to link to a non-used class method) is working in the provided example and not in my code?

Edit The cmake looks like:

add_library(lec_lib SHARED lec.cpp lec.h)
add_executable(lec_main main.cpp)
target_link_libraries(lec_main lec_lib)

Hence, the compiled library is linked with the executable.

Edit 2 Please avoid suggesting answers such as Why templates can only be implemented in the header file since I already know that the template has to be available to the compiler when the class is instantiated for a new type. My question is different. Why can I instantiate a type for which not all the template implementations are available as long as I do not use the specific class methods for which the template implementation is not provided at instantiation time (in the example case func())

Edit 3 Regarding the suggestion that this is a duplicate of What is an undefined reference/unresolved external symbol error and how do I fix it?. Again my question is different. I am looking for answers on why in the example I can instantiate LEC<char> when LEC<char>::func() is not visible for the compiler when it compiles the main program. And inthe case that this cannot be done and L3C<char>::func() is required to be linked, how to find why the method linkage is required while it is not being used (which is what happens in my real code).

apalomer
  • 1,895
  • 14
  • 36
  • I will read again more carefully this post that you mention, but I think my question is different. – apalomer Dec 18 '18 at 12:47
  • No, it's the same, you forgot to compile the two cpp files and link against the two object files. – Matthieu Brucher Dec 18 '18 at 12:47
  • Please, reconsider opening this question again. I've made it clear that it is different from the suggested duplicates. – apalomer Dec 18 '18 at 13:07
  • This is not a duplicate of the mentioned posts by any means. The OP is having the specific issue why his compiler is asking for the definition of a never-used function. – fieres Dec 18 '18 at 13:10
  • apalomer: It might be a policy of your specific compiler that it wants all members to be defined. With clang++, your files compile and work fine. Have you tried to implement func() in the header? If the code does not work for a specific template parameter, but it's never used, it might still compile. – fieres Dec 18 '18 at 13:17
  • @apalomer You don't call c.func() in your main(), which is where the failure occurs. With that added, it fails with both g++ and clang++ on my machine. I'd say just don't do that. – Michael Surette Dec 18 '18 at 14:11

0 Answers0