我正在尝试创建一类固定大小的 vector ,主要用于几何目的, 其中 vector 长度不变:
template<typename T, int n>
class FixedVector
{
private:
T m_rV[n]; // this is the only data member
public:
// class function members
...
}
这将具有编译器检查具有不兼容大小的 vector 的操作的优点。
我在尝试为此类构建运算符*时遇到问题(注意:它不是成员)。该运算符应将 vector 乘以标量,例如 3*[1,2,3]=[3,6,9]。
template<typename T, int n>
FixedVector<T,n> operator*(const T &rX, const FixedVector<T,n> &cV) const
{ typename std::pointer_to_binary_function<T,T,T> op=(util::times<T>);
FixedVector<T,n> cT(cV, std::bind1st(op, rX));
return cT;
}
其中 times 是 vector 标量成员的乘法函数
template<typename T>
inline T times(const T &t1, const T &t2)
{ return t1*t2;
}
第 4 行构造函数的代码是
template<typename T, int n>
FixedVector<T,n>::FixedVector(const T rV[n], T (*f)(const T &))
{ util::copy(m_rV, rV, n, f);
}
pointer_to_binary_function和bind1st是头文件中的STL函数(那些可以提供帮助的人应该已经知道这一点)。
调用时,我在 Visual Studio 2005 中收到以下编译器错误
util::FixedVector<int,4> x; 3*x;
:
fixed_vector.hpp(212) : error 2440:
'initializing' : cannot convert from 'T (__cdecl *)(const T &,const T &)'
to 'std::pointer_to_binary_function<_Arg1,_Arg2,_Result>'
with
[
_Arg1=int,
_Arg2=int,
_Result=int
]
No constructor could take the source type, or constructor overload resolution was ambiguous
testproject.cpp(18) : see reference to function template instantiation 'util::FixedVector<T,n> util::operator *<T,4>(const T &,const util::FixedVector<T,n> &)' being compiled
with
[
T=int,
n=4
]
看来 类型名 std::pointer_to_binary_function 被正确实例化为 std::binary_function 的指针 然而,时代仍然保留着它的基本特征: 'T (__cdecl *)(const T &,const T &)
--- 经过一些编辑 ----------------------------------------- -----------------------
有人向我表明,我的构造函数请求一个普通函数作为参数:T (*)(const T &t1, const T &t2),并且 STL 函数对象不会被接受。 链接在这里STL for_each充当如何进行更正的指南。
我开始从 util::copy 函数开始改变,由构造函数调用。
来自: 模板 void copy(T *dst, const T *src, size_t n, T (*f)(const T &)) { for (; n>0; n--, dst++, src++) { *dst = f(*src); } }
变成了
template<typename T, typename Function>
void copy(T *dst, const T *src, size_t n, Function f)
{ for (; n>0; n--, dst++, src++)
{ *dst = (*f)(*src);
} }
然后,构造函数本身就被模板化了。来自:
template<typename T, int n>
FixedVector<T,n>::FixedVector(const T rV[n], T (*f)(const T &))
{ util::copy(m_rV, rV, n, f);
}
就是现在
template<typename T, int n>
template<class Function>
FixedVector<T,n>::FixedVector(const FixedVector<T,n> &cV, Function f)
{ util::copy(m_rV, cV.m_rV, n, f);
}
还在模板实例化参数中添加了一些常量:
template<typename T, int n>
FixedVector<T,n> operator*(const T &rX, const FixedVector<T,n> &cV)
{ typename std::pointer_to_binary_function<const T,const T,T> op(times<T>);
FixedVector<T,n> cT(cV, std::bind1st(op, rX));
return cT;
}
但我仍然遇到相同的错误(只是 T 已被 const T 替换;请注意,添加 & 来指示引用(const T&)将触发错误,并且模板似乎对此有问题,Boost 和 TR1创建特殊的解决方案来解决这个问题 - 请参阅 Wikipedia TR1 reference wrapper )。
错误的确切行是这样的:
typename std::pointer_to_binary_function<const T,const T,T> op(times<T>);
所以我什至没有到达构造函数。
如果有一些额外的想法,我将非常感激。
最佳答案
您的函数util::times
有签名:
T times(const T&, const T&)
但是在这一行中:
typename std::pointer_to_binary_function<T,T,T> op=(util::times<T>);
std::pointer_to_binary_function
的构造函数正在期待:
T times(T, T)
您可以使用const T&
来解决这个问题作为参数模板参数:
typename std::pointer_to_binary_function<const T&, const T&, T> op(util::times<T>);
请注意,我删除了 =
在这里使用显式构造函数符号。至少在(我的)GCC 中,赋值语法被编译器拒绝。
由于您正在创建一个执行乘法的二进制仿函数,而不是自定义 times
函数和仿函数包装器,您可以直接使用 std::multiplies
达到同样的目的:
std::multiplies<T> op;
请注意,在下一行中,
FixedVector<T,n> cT(cV, std::bind1st(op, rX));
您正在调用一个采用 FixedVector<T, n>
的构造函数作为第一个参数,一元仿函数作为第二个参数。这与您发布的构造函数代码不兼容:
template<typename T, int n>
FixedVector<T,n>::FixedVector(const T rV[n], T (*f)(const T &))
{ util::copy(m_rV, rV, n, f);
}
因为这个需要一个普通数组和一个函数指针。
关于c++ - 使用C++函数库时无法正确实例化模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6925917/