8

因为我的一些代码需要在不同类型的矩阵之间进行隐式转换(例如。矩阵<int>矩阵<双>),我定义了一个模板复制构造函数矩阵<T>::矩阵(矩阵<U>常数&)而不是标准矩阵<T>::矩阵(矩阵<T>const&):

template类矩阵{公众:// ...模板<typename U>矩阵(矩阵<U>常量&);// ...私有的无符号int m_rows,m_cols;T*m_data;// ...};

在copy-constructor中添加适当的类型转换后,此方法可以在不同类型的矩阵之间完美转换。令人惊讶的是,在一个简单的copyconstructor运行的情况下,它会失败,并出现malloc错误:其中U==T。确实,使用默认值重载copy-constructor矩阵<T>:矩阵(矩阵<T>常量&)签名解决了这个问题。

这是一个糟糕的解决方案,因为它会导致大量复制构造函数代码(字面上是不变的复制和粘贴)。更重要的是,我不明白为什么会有双免malloc公司错误,没有重复的代码。此外,为什么它非常冗长template(模板)这里需要的语法与标准相反,而且要简洁得多,模板<类型名T,类型名U>?

模板化方法的完整源代码,在Mac OS 10.5上使用G++v4.0.1编译。

template(模板):矩阵(矩阵){m_rows=对象.GetNumRows();m_cols=对象GetNumCols();m_data=新T[m_rows*m_cols];for(无符号整数r=0;r<m行;++r){for(无符号int c=0;c<m_cols;++c){m_data[m_rows*r+c]=static_cast<T>(对象j(r,c));}}}

2个答案2

重置为默认值
13

它失败的原因是模板没有禁止复制构造函数的隐式声明。它将作为一个简单的转换构造函数,当重载解析选择对象时,可以使用它来复制对象。

现在,您可能在某处复制了矩阵,这将使用隐式定义的复制构造函数进行平面复制。然后,复制的矩阵和副本都会在其析构函数中删除相同的指针。

此外,为什么它非常冗长template(模板)需要语法

因为涉及到两个模板:Matrix(一个类模板)和转换构造函数模板。每个模板都有自己的模板子句和自己的参数。

你应该摆脱<T>顺便说一下,在你的第一行。定义模板时不会出现这种情况。

这是一个糟糕的解决方案,因为它会导致大规模复制构造函数代码

您可以定义一个成员函数模板来完成这项工作,并从转换构造函数和复制构造函数中委托。这样,代码就不会重复。


Richard在评论中说得很好,这让我修改了我的回答。如果从模板生成的候选函数比隐式声明的复制构造函数更匹配,则模板“获胜”,并将被调用。以下是两个常见示例:

结构A{模板<类型名T>A(T&){标准::cout<<“A(T&)”;}A(){}};整型main(){A A;A b(A);//模板获胜://A<A>(A&)--专业化//A(常数&);--隐式复制构造函数//(倾向于较少的资格)常数a1;A b1(a1);//隐式复制构造函数获胜://A(常数&)--专业化//A(A常量&)--隐式复制构造函数//(首选非模板)}

如果复制构造函数的任何成员具有

结构B{B(B&){}B(){}};结构A{模板<typename T>A(T&){标准::cout<<“A(T&)”;}A(){}B B;};整型main(){A A;A b(A);//隐式复制构造函数获胜://A<A>(A&)--专业化//A(A&);--隐式复制构造函数//(首选非模板)常数a1;A b1(a1);//模板获胜://A(常数&)--专业化//(隐式复制构造函数不可行)}
7
  • 你对malloc错误的解释听起来很贴切。编译器不能使用模板成员函数作为复制构造函数有什么具体原因吗?感谢您提供的信息和避免代码重复的建议。 评论 2009年8月9日0:32
  • 如果你有这个模板,它还不是一个函数。只有将其与一些模板参数一起使用,才能从中生成一个(member-)函数(称为专门化)。这也是成员模板不能是虚拟的原因:您事先不知道从中生成了什么函数。 评论 2009年8月9日1:02
  • 这很有意义——这不起作用,因为需要向前声明模板参数或包含实现的完整源代码。再次感谢。 评论 2009年8月9日3:33
  • 1
    “..模板永远不能用作复制构造函数。”:这有点误导。正确的语句是:“模板复制构造函数不禁止编译器生成的隐式复制构造函数”。这一点很重要的原因是,如果您提供的非模板复制构造函数的转换比模板构造函数的转换差,那么将选择模板构造函数。例如:“Matric(Matric const volarile&m)”。通常情况下,隐式生成的ctor获胜,因为它至少与模板一样好,而且它不是模板。 评论 2009年8月10日9:35
  • @理查德,关于转换序列,这一点很好。我会修改我的答案。 评论 2009年8月10日11:31
1

我不完全清楚您的问题,但我怀疑发生的情况是,在代码的某些地方使用了默认的复制构造函数(它只进行成员级复制)。请记住,不仅您实际编写的代码使用复制构造函数,编译器也使用它。

你的答案

单击“发布您的答案”,表示您同意我们的服务条款并确认您已阅读我们的隐私政策.

不是你想要的答案吗?浏览标记的其他问题问你自己的问题.