Search code examples
c++visual-studiotemplatesc++20

<Professional C++> 5th, base on chapter12-2-3, i write chapter 15-2 array, but report error LNK2019


I have customized a template class here and wanted to put the method definition and implementation in different files. I followed the previous simulation and wrote it down. Why did this error keep reporting no instances? I checked and wrote the following simulation, which should be fine, but it kept reporting errors. Please ask the big shots to help check what the problem is

  1. create day15.cpp
import mytestarray; // module name

#include <iostream>;
using namespace std;

int main()
{
    MyArray<int> my;
    system("pause");
}
  1. create module file, MyArrayTest.cppm
export module mytestarray;

export import :defv;
export import :impv;
  1. create MyArrayDefinition.cppm file
module;
#include<cstddef>

export module mytestarray:defv;
import <utility>;
import <memory>;
import <stdexcept>;
import <iostream>;
import <format>;
export template<typename T>
class MyArray
{
public:
    MyArray();
    virtual ~MyArray();

    MyArray& operator=(const MyArray& myarray) = delete;
    MyArray(const MyArray& myarray) = delete;

    MyArray(MyArray&& src) noexcept;
    MyArray& operator=(MyArray&& rhs) noexcept;

    T& operator[](size_t x);
    const T& operator[](size_t x) const;

    const T& getElementAt(size_t x) const;

    void setElementAt(size_t x, const T& value);

    size_t getSize() const noexcept;
private:
    static const size_t AllocSize{ 4 };
    void resize(size_t newSize);
    T* m_elements{ nullptr };
    size_t m_size{ 0 };
};
  1. create MyArrayDefinition.cppm file
module;
#include <cstddef>
export module mytestarray:impv;

import :defv;
export template<typename T>
MyArray<T>::MyArray()
{
    m_size = AllocSize;
    m_elements = new T[m_size]{};
}

export template<typename T>
MyArray<T>::~MyArray()
{
    delete[] m_elements;
    m_elements = nullptr;
}

export template<typename T>
MyArray<T>::MyArray(MyArray&& src) noexcept
    : m_elements {std::exchange(src.m_elements, nullptr)}
    , m_size {std::exchange(src.m_size, 0)} {}

export template<typename T>
MyArray<T>& MyArray<T>::operator=(MyArray&& rhs) noexcept
{
    if (this == &rhs)
    {
        return *this;
    }

    delete[] m_elements;
    m_elements = std::exchange(rhs.m_elements, nullptr);
    m_size = std::exchange(rhs.m_size, 0);
    return *this;
}

export template<typename T>
void MyArray<T>::resize(size_t newSize)
{
    auto newArray{ std::make_unique<T[]>(newSize) };
    for (size_t i = 0; i < m_size; i++)
    {
        newArray[i] = m_elements[i];
    }

    delete[] m_elements;
    m_size = newSize;
    m_elements = newArray.release();
}


export template<typename T>
void MyArray<T>::setElementAt(size_t x, const T& val)
{
    if (x >= m_size)
    {
        resize(x + AllocSize);
    }

    m_elements[x] = val;
}


export template<typename T>
T& MyArray<T>::operator[](size_t x)
{
    // TODO: 在此处插入 return 语句
    //std::cout << std::format("call no-const function") << std::endl;
    if (x >= m_size)
    {
        resize(x + AllocSize);
    }
    return m_elements[x];
}

export template<typename T>
const T& MyArray<T>::operator[](size_t x) const
{
    // TODO: 在此处插入 return 语句
//  std::cout << std::format("call const function") << std::endl;
    if (x >= m_size)
    {
        throw std::out_of_range{ "" };
    }
    return m_elements[x];
}

//export template<typename T>
//const T& MyArray<T>::operator[](size_t) const
//{
//  // TODO: 在此处插入 return 语句
//  std::cout << format("call const function") << std::endl;
//  if (x >= m_size)
//  {
//      static T nullValue{ T() };
//      return nullValue;
//  }
//  return m_elements[x];
//}


export template<typename T>
const T& MyArray<T>::getElementAt(size_t x) const
{
    if (x >= m_size)
    {
        throw std::out_of_range{ "" };
    }
    return m_elements[x];
}

export template<typename T>
size_t MyArray<T>::getSize() const noexcept
{
    return m_size;
}

when running report below is error

1>day15.obj : error LNK2019: 无法解析的外部符号 "public: __thiscall MyArray<int>::MyArray<int>(void)" (??0?$MyArray@H@@QAE@XZ::<!mytestarray>),
1>day15.obj : error LNK2019:  "public: virtual __thiscall MyArray<int>::~MyArray<int>(void)" (??1?$MyArray@H@@UAE@XZ::<!mytestarray>),函数 _main 中引用了该符号
1>D:\Project\CPlus\two\thir\CPlus\learnCPlus20\Debug\learnCPlus20.exe : fatal error LNK1120:

What is the problem, I referred to the following https://github.com/carlesmartin85/procpp5e/blob/65aedda6a92745beca48a5041411465a33cdf4cd/code/c12_code/02_Grid/02_MethodsInInterfacePartition/GridDefinition.cppm


Solution

  • In MSVC, separating the template class constructor and destructor will produce the error above .

    Temporary solution: Put both functions' definitions in the same file where they are declared (step 3 create MyArrayDefinition.cppm file).

    And please report the error to the Developer Community and post link here so that we can follow up.