-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;
inline T& operator()( size_t index );
inline const T& operator()( size_t index ) const;
template <size_t N> Vector<N,T> operator()(const  colon &cex) const;
.
.
}

以及相应的实现

template< size_t M, typename T >
template< size_t N>
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;

 }
}

用于测试功能的代码是

bool ok = true;

Vector< 4, double > v;
double data[] = { 1, 2, 3, 4 };

v.iter_set( data, data+4 );//just puts elements of data inside v with the same type

// test  Vector colon
{
    bool ok = true;
    Vector<3,long> test;
    test=v(colon(2,4));//Problem

}

现在的错误是

C2664: 'const double &Vector<M,T>::operator ()(size_t) const' : 
cannot convert parameter 1 from 'colon' to 'size_t'

编译器的输出是

error C2664: 'const double &Vector<M,T>::operator ()(size_t) const' : 
cannot convert parameter 1 from 'colon' to 'size_t'
with
[
M=4,
T=double
]
No user-defined-conversion operator available that can perform this conversion, 
or the operator cannot be called

???帮助表示赞赏

4

2 回答 2

1
template <size_t N> Vector<N,T> operator()(const  colon &cex) const;

本身是在 N 上模板化的,并且 N 的值不能从冒号推导出来,因此在重载集中不考虑它。

于 2012-09-25T11:10:44.697 回答
0

我有太多话要说,无法将其放入评论中,因此我将为此使用答案(尽管它不会直接回答您的问题):

您需要知道您的用例将是什么。如果你要对运行时变量做很多事情,那么在模板中实现它是没有意义的。如果您只想使用模板,那么您也需要使用class colon. 我会给你一些提示。

首先,让我比评论更详细地解释您的问题。

假设我们有一个Vector<5, int> vec;.

案例“编译时大小”:

//get the entries with indices 1 to 3 (including)
Vector<3, int> vec2 = vec(colon(1, 3));

对于此代码,所有内容在编译时都是已知的,因此可以在编译时执行此操作(尽管为此目的不必要的丑陋)。

案例“运行时大小”:

//we get the variables a and b as input from the user at runtime
Vector<?, int> vec2 = vec(colon(a, b));

看到那些ab变量了吗?当你编写程序时,你知道它们持有什么价值吗?不,你不能,因为用户应该输入它们。他们可能是0:0or0:442:1337,谁知道用户将输入什么(不小心)。当您不知道 的值a并且b您也不知道将代表什么时?,但是您必须在编译时知道,因为每个模板参数都必须在编译时知道。

现在你需要知道你想做什么。您是想使用a:b(运行时参数)还是只想输入常量,例如1:3(编译时参数)。根据这个你需要选择,如何实现Vector<n,T>::operator()

您会看到:一旦 的大小Vector取决于运行时值,它就无法在编译时确定,因此不可能返回正确大小的向量。

但是,您可以实现一个编译时大小和一个运行时大小的向量和冒号类,以便以更复杂的实现为代价来启用两者。他们会给出以下模式:

CompileTimeVector CompileTimeVector::operator()(CompileTimeColon);
RunTimeVector CompileTimeVector::operator()(RunTimeColon);
RunTimeVector RunTimeVector::operator()(CompileTimeColon);
RunTimeVector RunTimeVector::operator()(RunTimeColon);

这种模式对于任何在 Vector 和冒号的运行时和编译时类型之间进行互操作的操作都是必需的。

于 2012-09-25T16:47:20.973 回答