首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >模板内的模板方法-实例声明和类方法声明签名不同

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

Stack Overflow用户
提问于 2020-05-22 05:41:06
回答 1查看 26关注 0票数 0

我有一个模板化的类,并且在那个类中还有一个模板化的方法。模板化的方法需要不同的非显式但标准的typename,如下面的Class和method声明所示。

代码语言:javascript
运行
复制
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()方法的实现细节如下:

代码语言:javascript
运行
复制
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;
}

直观地看,main中使用此方法(convert_Matrix())的实例应该编译和链接,但只有当convert_Matrix()方法被实例调用时,E上才会出现替换/推导错误。如果没有在main中调用该方法实例,则编译时不会发生意外。

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

代码语言:javascript
运行
复制
#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,我尝试了两者的组合,为什么我使用的方法有效?为什么直截了当的方法(例如类声明)不起作用?

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

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

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

如果您有任何意见或备选解决方案,我们将不胜感激。

EN

回答 1

Stack Overflow用户

发布于 2020-05-22 06:05:20

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

标准库的std::get在用于从基于类型的元组中提取值时,也需要显式指定类型。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61944303

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档