c ++模板复制构造函数不可用或显式

时间:2016-06-07 13:04:06

标签: c++

我用模板复制构造函数编写了一个代码,以便更好地理解这个概念,因为我是新手,但下面的代码无法编译

#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)

3 个答案:

答案 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的转换器构造时,你试图做的事情是完全无逻辑的。无论如何编译器将优先考虑复制构造函数而不是转换器构造函数。

最终你的构造函数的定义永远不会被调用。