在类模板上覆盖方法,编译器看不到它,只能看到其他重载函数
overloadded method on a class template, compiler doesn't see it, see only other overloaded function
我对模板有些陌生,我正在尝试修改一些为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;
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;
}
这里的返回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
感谢的帮助
template <size_t N> Vector<N,T> operator()(const colon &cex) const;
它本身是在N上模板化的,并且N的值不能从冒号中推导出来,所以在重载集中不考虑它。
我有太多的话要说,无法将其放入评论中,所以我将使用答案(尽管它不会直接回答您的问题):
你需要知道你的用例是什么。如果您要对运行时变量做很多工作,那么在模板中实现它是没有意义的。如果只想使用模板,那么也需要使用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));
看到那些a
和b
变量了吗?当你编写程序时,你知道它们的值是多少吗?不,您不能,因为用户应该输入它们。它们可能是0:0
、0:4
或42: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和冒号的运行时和编译时类型之间进行互操作的操作都是必要的。
- 为什么使用SFINAE而不是函数重载
- 为什么我不能在 C++ 中的特定函数重载中调用同一函数的任何其他重载?
- c++:可变模板和函数重载
- 在缺少函数重载时抛出异常,并带有 std::variant 而不是编译时错误
- 解决模板成员函数重载
- 为什么不允许成员函数和非成员函数之间的函数重载?
- 推断模板化函数中的函数重载
- C++复制函数重载导致"must be a nonstatic member function"错误
- 为什么 std::sort 找不到合适的(静态成员)函数重载?
- 可变参数泛型 lambda 和函数重载
- C++中的函数重载和继承
- 当有右值构造函数可用时,为什么从右值调用类引用构造函数重载?
- C/C++ 可变参数宏函数重载
- 将基类的成员函数重载到其他派生类C++
- C++ 函数重载匹配
- C++函数重载,具体步骤是什么
- C++:使用 param pack 显式调用函数重载
- 隐式生成的函数重载用于右值参数?
- 使用函数重载输入运算符
- 运算符重载函数上的函数重载