类模板上的 overloadd 方法,总是无法将函数定义与声明匹配

overloadded method on a class template, always gives unable to match function definition to declaration

本文关键字:函数 定义 声明 overloadd 方法      更新时间:2023-10-16

我对模板不熟悉,我正在尝试修改一些为 c++ 提供矩阵和向量操作的库,我有一个向量类,我正在尝试重载运算符()以使其处理这样的操作 Vector(2:5) 将返回一个包含原始向量的元素 2,3,4,5 的向量,并且我正在使用一个名为冒号的类,其中冒号(2:5) 将表示 (2:5) 效果,因为我发现 C++ 具有无运算符:。 希望我做了一个适当的介绍。 相关代码如下

向量类

template< size_t M, typename T = float >
class Vector
{
public:
typedef T   value_type;
Vector operator-( const Vector& other ) const;
template <size_t N, typename T> Vector<N,T> operator()(const  colon &cex) const;
.
.
}

以及相应的实现

template< size_t M, typename T >
template< size_t N,T>
Vector<N,T>
Vector<M,T>::operator()( const colon &cex ) const
{
long i, ii, st = 0, in = 0, en = 0, s;
cex.apply(M, st, in, en, s);
if (s && (st>0) && (st>M))
{
Vector<N,T> result;
for (i=st,ii=0;i+=in,ii++;i<=en,ii<N)
{
result(ii)=array(i);
return result;
}
}
return 0;
}

这里的返回 0 只是一个占位符,它应该返回一个空向量。 冒号类(取自另一个库并由我修改)。

class colon
{
public:
/// Colon expression '(:)'
colon() { _flag = 'a'; }
/// Colon expression of type '(2:5)'
colon(long s, long e) { _s = s; _i = 1; _e = e; _flag = 'r'; }
void apply(long s, long &f, long &i, long &l, long &n) const;
private:
/// Type of colon expression.
char _flag;
/// First index.
long _s;
/// Increment.
long _i;
/// Last index.
long _e;
}; /* class colon */

并且相关的实现是

void
colon::apply(long n, long &st, long &in, long &en,
long &le) const
{
switch (_flag)
{
case 'r':
if ((_i == 0 ) || ((_e - _s) / _i < 0 )) le = 0;
else
{
st = _s;
in = _i;
en = _e - (_e - _s) % _i;
le = (_e - _s) / _i + 1;
}
break;
case 'a':
if (n)
{
st = 1;
in = 1;
en = n;
le = n;
}
else le = 0;
break;
}
}

编译此代码时,我总是收到错误

错误1 错误 C2244:"Vector::运算符 ()":无法将函数定义与现有声明匹配

编译器的输出为

error C2244: 'Vector<M,T>::operator ()' : unable to match function 
definition to an existing declaration
definition
'Vector<N,T> Vector<M,T>::operator ()(const colon &) const'
existing declarations
'Vector<N,T> Vector<M,T>::operator ()(const colon &) const'

那么我在这里做错了什么?

在你的声明中,你写道:

template< size_t M, typename T = float >
class Vector
{
template <size_t N, typename T> 
Vector<N,T> operator()(const  colon &cex) const

在您的定义中,您写道:

template< size_t M, typename T >
template< size_t N,T>
Vector<N,T>
Vector<M,T>::operator()( const colon &cex ) const

请注意第二个模板行的差异:

template <size_t N, typename T> 

与。

template< size_t N,T>

你错过了那里的typename。因此,您不希望将类型传递给 T,而是希望传递T的实例(这仅在T是整型时才有可能)。

这表明您的声明和定义实际上有所不同,错误来自何处。

由于您的第二个T会隐藏第一个(这是不允许的 - 请参阅评论),我认为您要么想重命名第二个T并在定义中添加typename,要么想完全删除第二个T

第一个问题是你写错了模板函数参数:template<size_t N,T>.应为template<size_t N, typename T>,否则会被视为非类型模板参数(某些特定值为T)。

第二个问题是函数模板参数名称T不明确。编译器无法从类模板参数或函数 1 中知道它应该使用哪个T?请记住,函数和类模板参数是不相关的。所以你需要重命名它:

template<size_t M, typename T> class Vector
{
public:
template <size_t N, typename X> Vector<N,X> operator()() const;
};
template<size_t M, typename T>
template<size_t N, typename X> Vector<N,X> Vector<M,T>::operator()() const
{ 
}

但实际上,如果你不需要交叉类型操作,并且X总是与T相同的类型,你可以在函数中跳过它,只按大小对其进行参数化:

template<size_t M, typename T> class Vector
{
public:
template <size_t N> Vector<N,T> operator()() const;
};
template<size_t M, typename T>
template<size_t N> Vector<N,T> Vector<M,T>::operator()() const
{ 
}