模板中的模板方法 - 实例声明和类方法声明签名不同

template method within template - instance declaration and class method declaration signature differs

本文关键字:声明 类方法 实例 模板方法      更新时间:2023-10-16

我有一个模板化类,在该类中还有一个进一步的模板化方法。模板化方法需要不同的非显式但标准的类型名,如下面的类和方法声明所示。

template <typename T>
class Matrix
{
public:
// constructors
Matrix(int  rows, int cols,T _initial);
Matrix():mCols(0),mRows(0),mdata(0)
{   }
Matrix(int rows,int cols, 
std::vector<T>&X):mRows(rows),mCols(cols),mdata(X)
{ }
int get_numofrows(); // returns  mRows
int get_numofcols()  // returns mCols
void show_matrix();  // prints matrix on console, which is really the vector <T> mdata
template<typename E> // <----focus is here
Matrix<E> convert_Matrix(); // <----and here
// other  methods not relevant to this problem go here
// ....
private:
int mRows;
int mCols;
std::vector<T> mdata;
};

方法convert_Matrix()的实现细节如下所示:

template<T>
template<E>
Matrix<E> Matrix<T>::convert_Matrix()
{ 
// creates a vector cast of all elements of underlying
// vector of type T to vector elements of type E
// eg; vector<E> D uses vector copy constructor
std::vector<E> D(this->mdata.begin(), this->mdata.end());
// uses vector D as an argument to create the rest of the matrix
Matrix<E> MX(this->get_numofrows(),this->get_numofcols(),D);
return MX;
}

直观地说,使用此方法(convert_Matrix()(的主实例似乎应该编译和链接,但只有在实例调用convert_Matrix((方法时才抱怨E上的替换/扣除错误。如果未在 main 中调用方法实例,则编译时不会发生任何事件。

开发了以下代码来测试方法convert_Matrix()

#include " Matrix.h"
int main()
{
std::vector<float> Mz = {
139.342, 144.167,149.543,153.678,155.987,155.21,155.23,155.876,
144.112,151.34,153.6789,156.34,159.0124,156.678,156.56,156.6543,
150.456,155.123,160.45,163.876,158.432,156.78,156.123,156.525,
159.567,161.267,162.567,160.67,160.59,159.001,159.675,159.456,
159.876,160.743,161.456,162.432,162.876,155.543,155.123,155.840,
161.111,161.222,161.333,161.678,160.543,157.890,157.1212,157.987,
162.111,162.222,161.333,163.987,162.888,157.543,157.666,157.345,
162.234,162.777,161.888,161.444,163.99,158.775,158.234,158.98
};
Matrix<float> FF(8,8,Mz);
// Matrix<int>BV = FF.convert_Matrix(); <--deduction/substitution error couldn't deduce E
Matrix<int>BV = FF.convert_Matrix<int>();// <---works
BV.show_Matrix();
FF.show_Matrix();
}

我成功地让上面的代码使用FF.convert_Matrix的实例实例化进行编译和执行,如上所示,但我不确定这种方法和定义在语法上是否准确。我尝试了更多的类型转换,它们似乎都可以正确编译、链接和执行,而不会发生任何事件(替换适当的类型代替int( 这让我想到以下问题

1(我可以从逻辑角度理解,如果编译器链接器抱怨类型推导,我应该尝试帮助它。我试过auto,我试过decltype, 我尝试了两者的组合,为什么我使用的方法有效?为什么直接的方法(例如.class声明(不起作用?

2(通过反复试验,我偶然发现了上面说明的这个解决方案。ISO标准中是否有某种规则来定义我做了什么?

3(有没有更好的方法来做同样的事情?为什么类定义中的方法签名与在实例中实例化时不同的签名?

4(我认为这个解决方案问题最好通过专业化和更多的代码来解决。我偶然发现的解决方案有效,那么为什么要添加更多代码呢? 为了清楚起见,我宁愿只更改类声明和实现语义中的最小值

您的任何意见或替代解决方案将不胜感激。

编译器不会查看赋值左侧的类型来推断模板参数。 编译器看到的是FF.convert_Matrix(),无法推导出convert_Matrix的模板参数。 这就是您需要显式指定模板参数的原因。

标准库的std::get,当用于根据类型从元组中提取值时,也需要明确指定类型。