我用模板复制构造函数编写了一个代码,以便更好地理解这个概念,因为我是新手,但下面的代码无法编译
#include <iostream>
#include <vector>
using namespace std;
template <typename T>
class Grid
{
public:
explicit Grid(size_t inWidth = kDefaultWidth, size_t inHeight = kDefaultHeight);
virtual ~Grid();
template <typename E>
Grid(const Grid<T>& src);
static const size_t kDefaultWidth = 10;
static const size_t kDefaultHeight = 10;
std::vector<std::vector<T>> mCells;
size_t mWidth, mHeight;
};
template <typename T>
template <typename E>
Grid<T>::Grid(const Grid<T>& src)
{
cout << "Copy constructor working " << endl;
}
int main()
{
Grid<double> myDoubleGrid;
Grid<double> newDoubleGrid(myDoubleGrid);
return 0;
}
在Visual Studio中编译上述代码时出现以下错误: -
错误: -
严重级代码描述项目文件行抑制状态 错误C2558类&#39;网格&#39;:没有可用的复制构造函数或复制构造函数已声明&#39;显式&#39;
我试图用E替换参数模板,它显示更多错误(奇怪的)
template <typename T>
template <typename E>
Grid<T>::Grid(const Grid<E>& src)
{
cout << "Copy constructor working " << endl;
}
错误:
严重级代码描述项目文件行抑制状态 错误LNK2019未解析的外部符号&#34; public:__ thishisall Grid :: Grid(unsigned int,unsigned int)&#34;函数_main
中引用了(?? 0?$ Grid @ N @@ QAE @ II @ Z)错误LNK1120 2未解析的外部
错误LNK2019未解析的外部符号&#34; public:virtual __thiscall Grid :: ~Grid(void)&#34;函数&#34; public:virtual void * __thiscall Grid ::`scalar deletion destructor&#39;(unsigned int)&#34;(?? 1?$ Grid @ N @@ UAE @ XZ) (?? _ G?$ Grid @ N @@ UAEPAXI @ Z)
答案 0 :(得分:10)
模板构造函数永远不是(!)一个复制构造函数。代码中的构造函数只是一个转换构造函数。
您可能想要两者:
#include <iostream>
#include <vector>
// Please do not have this ugliness in a header!
using namespace std;
template <typename T>
class Grid
{
public:
explicit Grid(size_t inWidth = kDefaultWidth, size_t inHeight = kDefaultHeight)
// initialize members ...
{}
// Without this copy-constructor the compiler generates a copy-constructor
// (with no output, of course)
Grid(const Grid& src)
// initialize members ...
{
cout << "Copy constructor" << endl;
}
template <typename E>
Grid(const Grid<E>& src)
// initialize members ...
{
cout << "Converting constructor" << endl;
}
static const size_t kDefaultWidth = 10;
static const size_t kDefaultHeight = 10;
size_t mWidth, mHeight;
};
int main()
{
Grid<double> myDoubleGrid;
Grid<double> newDoubleGrid(myDoubleGrid); // Copy constructor
Grid<int> newIntGrid(myDoubleGrid); // Converting constructor
return 0;
}
另见:
答案 1 :(得分:1)
请注意,Grid<T>(Grid<U> const&)
在技术上不是复制构造函数,它是转换构造函数。编译器仍为您生成复制构造函数。
答案 2 :(得分:1)
由于你的愚蠢错误,你称之为危险错误的事情正在发生: -
1)您已为构造函数和析构函数提供了声明。正如你所说,它是你唯一的源文件。这意味着您必须没有定义它们,这是您获得链接器错误的原因。有时,这些非常简单的问题可能非常危险且耗时。
如果您不想提供任何详细的实施,您可以用一对括号替换分号。
2)当你创建一个类似于复制构造函数的ssignature的转换器构造时,你试图做的事情是完全无逻辑的。无论如何编译器将优先考虑复制构造函数而不是转换器构造函数。
最终你的构造函数的定义永远不会被调用。