没有匹配函数时返回不同的模板类型从原来 [英] no matching function when return different template type from the original

查看:216
本文介绍了没有匹配函数时返回不同的模板类型从原来的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写了一个简单的模板矩阵类,getMat函数应该返回一个不同大小的原始子矩阵,所以我编码如下:

  template< typename T,size_t m,size_t n,typename _Prd> 
模板< size_t _m,size_t _n>
Matrix< T,_m,_n,_Prd> Matrix< T,m,n,_Prd> :: getMat(const size_t& ulrow,const size_t& ulcol)const
{
assert(_m + ulcol< = m& < = n);
T temp [_m * _n];
for(size_t j = 0; j <_m; ++ j)
for(size_t i = 0; i <_n; ++ i)
temp [j * _n + i] = data [(ulrow + j)* n + ulcol + i];
return Matrix< T,_m,_n,_Prd>(temp);
}

然后我这样调用:

  Matrix< double,4,4& testmat2(100.0); 
Matrix< double,2,2> testmat4 = testmat2.getMat(0,0);

并显示如下错误:

  main.cpp:127:error:没有匹配的函数调用'Matrix< double,4ul,4ul,std :: equal_to< double> > :: getMat(size_t,size_t)'

所以我的问题是为什么编译器不检测这个getMat函数?



更新:



它工作:

 模板< typename T,size_t m,size_t n,typename _Prd> 
template< size_t _m,size_t _n>
void Matrix< T,m,n,_Prd> :: getMat(Matrix< T,_m,_n,_Prd& result,const size_t& ulrow,const size_t& ulcol)const
{
assert(_m + ulcol< = m&& _n + ulrow< = n);

for(size_t j = 0; j <_m; ++ j)
for(size_t i = 0; i <_n; ++ i)
result [ j * _n + i] = data [(ulrow + j)* n + ulcol + i]

}

这是通过将子矩阵修改为引用。



所以我的问题是,当这个函数返回一个不同的模板类型(同一对象)时,编译器根本不检测这个函数。



但我之前使用这种技术对许多转换运算符和他们工作。
例如,这个工程:

 模板< typename T,int cn,typename _Prd> 
template< typename U,typename _Prd2>
Vec< T,cn,_Prd> :: operator Vec< U,cn,_Prd2>()const
{
U temp [cn]
for(int i = 0; i temp [i] = static_cast (this-> data [i]
Vec< U,cn,_Prd2> v(temp);
return v;
};



Update2:



我根据iammilind修改代码:

  template< size_t _m,size_t _n> 
Matrix< T,_m,_n,_Prd> getMat< _m,_n>(const size_t& ulrow,const size_t& ulcol)const;
//类中的声明。

template< typename T,size_t m,size_t n,typename _Prd>
template< size_t _m,size_t _n>
Matrix< T,_m,_n,_Prd>矩阵< T,m,n,_Prd> :: getMat< _m,_n>(const size_t& ulrow,const size_t& ulcol)const
{
assert(_m + ulcol < & _n + ulrow< = n);
T temp [_m * _n];
for(size_t j = 0; j <_m; ++ j)
for(size_t i = 0; i <_n; ++ i)
temp [j * _n + i] = data [(ulrow + j)* n + ulcol + i];
return Matrix< T,_m,_n,_Prd>(temp);
}

我称为:

  Matrix< double,2,2& testmat7 = testmat2.getMat 2,2(0,0); 

但不能编译:

 在main.cpp中包含的文件中:13:
Matrix.hpp:125:error:'<'令牌之前的初始化程序
从main中包含的文件。 cpp:13:
Matrix.hpp:268:error:'<'token
之前的初始化程序main.cpp:在函数'int main(int,char **)':
main.cpp:135:error:'class Matrix< double,4ul,4ul,std :: equal_to< double> >'没有名为'getMat'的成员
main.cpp:135:错误:数字常量之前的预期未限定标识符

感谢。

解决方案

当您有此声明时

  template< typename T,size_t m,size_t n,typename _Prd> 
template< size_t _m,size_t _n>
Matrix< T,_m,_n,_Prd> Matrix< T,m,n,_Prd> :: getMat(const size_t& ulrow,const size_t& ulcol)const


$ b b

编译器需要推导出6个模板参数。其中四个(即 T m n _Prd )可以从调用函数的对象中推导出来。其他两个,即 _m _n )无法推导。您可以明确指定它们,但:

  Matrix< double,4,4& testmat2(100.0); 
Matrix< double,2,2> testmat4 = testmat2.getMat< 2,2(0,0);

如果 testmat2 ,您需要插入额外的模板关键字:

  template< ; int Size> 
void f(){
Matrix< double,4,Size> testmat2(100.0);
Matrix< double,2,2> testmat4 = testmat2.template getMat< 2,2(0,0);
}

编译器不会使用分配结果的类型来推断模板参数(该类型有时被使用,但只有当有一个就绪重载集合,并且它需要选择一个函数指针的地址或一个成员函数指针,我想)。



转换运算符可以推导出额外的参数,因为它实际上没有返回类型,但获得另一个参数,它可以从中推导出模板参数。您以后更新的错误可能是由于您声明该函数的方式:

 模板< size_t _m,size_t _n> ; 
Matrix< T,_m,_n,_Prd> getMat< _m,_n>(const size_t& ulrow,const size_t& ulcol)const;

< _m,_n> getMat()不要去那里。


I wrote a simple template matrix class, the getMat function should return a sub matrix of the original with different size , so I coded like this:

template <typename T, size_t m, size_t n, typename _Prd>
template<size_t _m, size_t _n> 
Matrix<T,_m,_n,_Prd> Matrix<T,m,n,_Prd>::getMat(const size_t& ulrow, const size_t& ulcol ) const 
{
    assert(_m+ulcol <= m && _n+ulrow <= n) ;
    T temp[_m*_n] ;
    for (size_t j = 0 ; j < _m ; ++j)
        for (size_t i = 0 ; i < _n ; ++i)
            temp[j*_n+i] = data[(ulrow + j) * n + ulcol+i] ;
    return Matrix<T,_m,_n,_Prd>(temp) ;
}

Then I call it like this:

Matrix<double, 4,4> testmat2(100.0) ;
Matrix<double,2,2> testmat4 =  testmat2.getMat(0,0) ;

And it shows error like this:

main.cpp:127: error: no matching function for call to ‘Matrix<double, 4ul, 4ul, std::equal_to<double> >::getMat(size_t, size_t)’

So my question is why compiler doesn't detect this getMat function ?

Update:

I tried code in this way and it works:

template <typename T, size_t m, size_t n, typename _Prd>
template<size_t _m, size_t _n> 
void Matrix<T,m,n,_Prd>::getMat(Matrix<T,_m,_n,_Prd>& result, const size_t& ulrow, const size_t& ulcol) const
{
    assert(_m+ulcol <= m && _n+ulrow <= n) ;

    for (size_t j = 0 ; j < _m ; ++j)
        for (size_t i = 0 ; i < _n ; ++i)
            result[j*_n+i] = data[(ulrow + j) * n + ulcol+i] ;

}

This is to pass the sub matrix to be modified as a reference.

So my problem is that when this function return a different template type (same object), the compiler doesn't detect this function at all.

But I used this technique before on many conversion operators and they work. For example, this one works:

template<typename T, int cn, typename _Prd>
template<typename U, typename _Prd2>
Vec<T,cn,_Prd>::operator Vec<U,cn,_Prd2>() const 
{
  U temp[cn] ;
  for (int i = 0 ; i < cn ; ++i)
    temp[i] = static_cast<U>(this->data[i]) ;
  Vec<U,cn,_Prd2> v(temp) ;
  return v ;
};

Update2:

I modified the code according to iammilind:

template<size_t _m, size_t _n> 
Matrix<T,_m,_n,_Prd> getMat<_m,_n>(const size_t& ulrow, const size_t& ulcol) const ;
// the declaration in the class.

template <typename T, size_t m, size_t n, typename _Prd>
template<size_t _m, size_t _n> 
Matrix<T,_m,_n,_Prd> Matrix<T,m,n,_Prd>::getMat<_m,_n>(const size_t& ulrow, const size_t& ulcol ) const 
{
    assert(_m+ulcol <= m && _n+ulrow <= n) ;
    T temp[_m*_n] ;
    for (size_t j = 0 ; j < _m ; ++j)
        for (size_t i = 0 ; i < _n ; ++i)
            temp[j*_n+i] = data[(ulrow + j) * n + ulcol+i] ;
    return Matrix<T,_m,_n,_Prd>(temp) ;
}

And I call it as:

Matrix<double,2,2> testmat7 = testmat2.getMat<2,2>(0,0) ;

But it doesn't compile:

In file included from main.cpp:13:
Matrix.hpp:125: error: expected initializer before ‘<’ token
In file included from main.cpp:13:
Matrix.hpp:268: error: expected initializer before ‘<’ token
main.cpp: In function ‘int main(int, char**)’:
main.cpp:135: error: ‘class Matrix<double, 4ul, 4ul, std::equal_to<double> >’ has no member named ‘getMat’
main.cpp:135: error: expected unqualified-id before numeric constant

Thanks.

解决方案

When you have this declaration

template <typename T, size_t m, size_t n, typename _Prd>
template<size_t _m, size_t _n> 
Matrix<T,_m,_n,_Prd> Matrix<T,m,n,_Prd>::getMat(const size_t& ulrow, const size_t& ulcol ) const

The compiler needs to deduce 6 template arguments. Four of these (i.e., T, m, n, and _Prd) can be deduced from the object you call the function. The other two, i.e., _m and _n) cannot be deduced. You could explicit specify them, though:

Matrix<double, 4,4> testmat2(100.0);
Matrix<double,2,2> testmat4 = testmat2.getMat<2, 2>(0,0);

If testmat2 ends up being a dependent name, you need to slip in an extra template keyword:

template <int Size>
void f() {
    Matrix<double, 4, Size> testmat2(100.0);
    Matrix<double, 2, 2>    testmat4 = testmat2.template getMat<2, 2>(0,0);
}

The compiler won't use the type the result is assigned to to deduce the template arguments (the type is sometimes used but only if there is a ready overload set and it needs to choose the address of a function pointer or a member function pointer out of these, I think).

The conversion operator can deduce the additional arguments because it doesn't really have a return type but gets another argument from which it can potentially deduce template arguments. The errors you get for your later updates are probably due to the way you declare the function:

template<size_t _m, size_t _n> 
Matrix<T,_m,_n,_Prd> getMat<_m,_n>(const size_t& ulrow, const size_t& ulcol) const ;

The <_m, _n> after getMat() don't go there.

这篇关于没有匹配函数时返回不同的模板类型从原来的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆