1

我对模板有点陌生,我正在尝试修改一些为 c++ 提供矩阵和向量操作的库,我有一个向量类,我试图重载 operator() 以便它处理像这样的操作 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;
}

这里的 return 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::operator ()”:无法将函数定义与现有声明匹配

编译器的输出是

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'

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

4

2 回答 2

1

在您的声明中,您写道:

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

于 2012-09-25T10:14:35.040 回答
1

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

第二个问题是函数模板参数名称T有歧义。编译器无法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
{ 
}
于 2012-09-25T10:35:05.367 回答