0

I've below Array definition in file templates.hpp

#include <cstddef>
#include <iostream>
using namespace std;

template <typename T>
class Array {
private:
  T* elements;
  size_t count;

public:
  Array(size_t size);
  Array(const Array& other);
  Array(Array&& other);
  virtual ~Array();
  T& operator[](size_t index);
  const T& operator[](size_t index) const;
  Array& operator=(const Array& other);
  Array&& operator=(Array&& other);
  size_t size() { return count; }
};

Below is my templates.cpp file

#include "templates.hpp"
#include <iostream>
#include <cstddef>
using namespace std;


template <typename T>
Array<T>::Array(size_t arraySize)
  try: elements { new T[arraySize]}, count {arraySize} {
    cout<< "sucessfully created the array" << endl;
       }
  catch(const exception& e){
    cerr << " Memory Allocation failure in Array Constructor." << endl;
  }

  template <typename T>
  inline Array<T>::Array(const Array &other) try : elements {
    new T[other.size()]}, count { other.size }
  
  {
        cout<< "sucessfully created the array" << endl;

  }
catch(const exception& e ) {
  
 }

I'm using catch2 library to test my code. Below is my templates_test.cpp file.

#include <iostream>
#include <memory>
#define CATCH_CONFIG_MAIN
#include "catch.hpp"
#include "templates.hpp"
#include <cstddef>
using namespace std;

TEST_CASE("initialize the array", "Array init") {
   Array<int> data {(size_t)5};

}

I'm using cmake to build this project and test. My CMakeLists.txt file is -

cmake_minimum_required(VERSION 3.20 FATAL_ERROR)

project(chapter-01 LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)

add_library(templates templates.hpp templates.cpp)

add_executable(templates_test templates_test.cpp catch.hpp)
target_link_libraries(templates_test templates)

enable_testing()

add_test(NAME catch_template_test COMMAND $<TARGET_FILE:templates_test> --success)

I created build directory and running cmake commands inside build directory. cmake .. is working fine. I ran cmake --build . commands failed. Below is the error trace.

cmake --build . 18:09:50 Consolidate compiler generated dependencies of target templates [ 50%] Built target templates Consolidate compiler generated dependencies of target templates_test [ 75%] Building CXX object CMakeFiles/templates_test.dir/templates_test.cpp.o [100%] Linking CXX executable templates_test /usr/bin/ld: CMakeFiles/templates_test.dir/templates_test.cpp.o: in function ____C_A_T_C_H____T_E_S_T____0()': templates_test.cpp:(.text+0x19eee): undefined reference to Array::Array(unsigned long)' /usr/bin/ld: templates_test.cpp:(.text+0x19f52): undefined reference to Array<int>::~Array()' /usr/bin/ld: templates_test.cpp:(.text+0x19f92): undefined reference to Array::~Array()' collect2: error: ld returned 1 exit status make[2]: *** [CMakeFiles/templates_test.dir/build.make:98: templates_test] Error 1 make1: *** [CMakeFiles/Makefile2:85: CMakeFiles/templates_test.dir/all] Error 2 make: *** [Makefile:101: all] Error 2

I check this stackoverflow post and its original post. I'm using cmake where those post author used gcc to compile directly.

Also, I've added both files templates.hpp templates.cpp in the add_library too.

How can I fix this issue?

user51
  • 8,843
  • 21
  • 79
  • 158
  • Use a different extension for your `templates.cpp` file, e.g. `templates.tcc`. – πάντα ῥεῖ Apr 12 '21 at 22:31
  • I tried but it is not working – user51 Apr 12 '21 at 22:35
  • I get error `cmake error: Cannot determine link language for target "templates".` – user51 Apr 12 '21 at 22:36
  • You have to change the `#include` statement in the header accordingly of course. That shouldn't be compiled directily, but via inclusion of `templates.hpp` only. – πάντα ῥεῖ Apr 12 '21 at 22:36
  • The real issue here is virtual destructor is should be like this `virtual ~Array(){};`. – user51 May 02 '21 at 01:52
  • @πάνταῥεῖ - could you please reopen this issue for me. – user51 May 02 '21 at 01:52
  • If you're writing a self answer please mention how you actually separated the template implementation, thus the former duplicate didn't apply. If it appears as an automatically build and linked source, you may end up with _multiple definition_ problems issued by the linker. – πάντα ῥεῖ May 02 '21 at 07:41
  • Actually I combined the template and its implementation and still I got the error. After I implmented destructor then the build is successful. – user51 May 03 '21 at 02:45

0 Answers0