c++ - 使用C++函数库时无法正确实例化模板

标签 c++ templates functional-programming

我正在尝试创建一类固定大小的 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/

相关文章:

c++ - 将参数传递给模板

python - 将链接列表传递给 Django 模板

scala - 在 Scala 中获取父类(super class)函数

c++ - 将值分配给原子用户定义结构的数组

c++ - 托管 C++ std::string 在非托管 C++ 中不可访问

c++ - 无法从 int 推断出 'const' ... 的模板参数

java - 谷歌 Guava : Supported way to get elements of a collection that comply with a given predicate?

Scalaz 自动类型类解析

c++ - 使用 ADS(备用数据流)隐藏可执行文件

c++ - Parent 类型的继承容器不能容纳 child ?