C++ 将函子作为C+传递+;模板参数
作为对我个人启发的练习,我使用表达式模板实现向量数学。我想实现一些操作,将相同的一元函数应用于向量表达式的所有元素。到目前为止,我是这样做的 我的基本向量表达式模板是这样实现的C++ 将函子作为C+传递+;模板参数,c++,templates,C++,Templates,作为对我个人启发的练习,我使用表达式模板实现向量数学。我想实现一些操作,将相同的一元函数应用于向量表达式的所有元素。到目前为止,我是这样做的 我的基本向量表达式模板是这样实现的 template <typename E> class VectorExpr { public: int size() const { return static_cast<E const&>(*this).size(); } float operator[](int i) co
template <typename E>
class VectorExpr {
public:
int size() const { return static_cast<E const&>(*this).size(); }
float operator[](int i) const { return static_cast<E const&>(*this)[i]; }
operator E& () { return static_cast<E&>(*this); }
operator E const& () const { return static_cast<const E&>(*this); }
}; // class VectorExpr
class Vector2 : public VectorExpr<Vector2> {
public:
inline size_t size() const { return 2; }
template <typename E>
inline Vector2(VectorExpr<E> const& inExpr) {
E const& u = inExpr;
for(int i = 0; i < size(); ++i)
mTuple[i] = u[i];
}
private:
float mTuple[2];
};
模板
类vectoexpr{
公众:
int size()常量{return static_cast(*this).size();}
浮点运算符[](int i)const{return static_cast(*this)[i];}
运算符E&({返回静态_cast(*this);}
运算符E const&()const{return static_cast(*this);}
}; // 类vectoexpr
然后,一个被认为是向量的物体会像这样
template <typename E>
class VectorExpr {
public:
int size() const { return static_cast<E const&>(*this).size(); }
float operator[](int i) const { return static_cast<E const&>(*this)[i]; }
operator E& () { return static_cast<E&>(*this); }
operator E const& () const { return static_cast<const E&>(*this); }
}; // class VectorExpr
class Vector2 : public VectorExpr<Vector2> {
public:
inline size_t size() const { return 2; }
template <typename E>
inline Vector2(VectorExpr<E> const& inExpr) {
E const& u = inExpr;
for(int i = 0; i < size(); ++i)
mTuple[i] = u[i];
}
private:
float mTuple[2];
};
class Vector2:公共VectorExpr{
公众:
内联大小\u t size()常量{return 2;}
模板
内联向量2(向量导出常量和内联向量){
E const&u=不合格;
对于(int i=0;i
假设我想将std::sin应用于表达式的所有元素
template <typename E>
class VectorSin : public VectorExpr<VectorSin<E> > {
E const& mV;
public:
VectorSin(VectorExpr<E> const& inV) : mV(inV) {}
int size() const { return mV.size(); }
float operator [] (int i) const { return std::sin(mV[i]); }
};
模板
类VectorSin:公共vectoexpr{
E const&mV;
公众:
VectorSin(vectoexpr const&inV):mV(inV){
int size()常量{return mV.size();}
浮点运算符[](int i)常量{return std::sin(mV[i]);}
};
问题=>如果我想添加更多的函数,我会复制粘贴我对sin函数所做的操作,对于每个函数(比如cos、sqrt、fabs等等)。如何避免这种复制粘贴?我尝试了一些东西,发现我的能量仍然不足。不允许增强^模板
template <typename F, typename E>
class VectorFunc : public VectorExpr<VectorFunc<F, E> > {
E const& mV;
public:
VectorSin(VectorExpr<E> const& inV) : mV(inV) {}
int size() const { return mV.size(); }
float operator [] (int i) const { return f(mV[i]); }
// this assumes the Functor f is default constructible, this is
// already not true for &std::sin. Adding the constructor that
// takes f, is left as an exercise ;)
F f;
};
类VectorFunc:public VectorExpr{
E const&mV;
公众:
VectorSin(vectoexpr const&inV):mV(inV){
int size()常量{return mV.size();}
浮点运算符[](int i)常量{return f(mV[i]);}
//这假设函子f是默认可构造的,这是
//对于&std::sin,已不是true。正在添加
//取f,留作练习;)
F;
};
除了答案by之外,标准的
函数不是函子,因此您不能直接使用它们来指定类的独特专业化,也就是说,对于std::sin和std::cos,您不会有单独的模板实例化(我猜你的目标是什么?如果我误解了你的意思,请纠正我)
您可以创建一个包装器,以便将函数指针映射到不同的类型,例如
#include <iostream>
template< void (*FuncPtr)() > struct Func2Type
{
void operator() () { FuncPtr(); }
};
void Hello() { std::cout << "Hello" << std::endl; }
void World() { std::cout << "world" << std::endl; }
int main()
{
Func2Type<Hello> test1;
Func2Type<World> test2;
test1();
test2();
}
#包括
模板struct Func2Type
{
void运算符()({FuncPtr();}
};
void Hello(){std::cout因为您正在学习,所以应该将C++11的lambdas与std::for_each()一起使用()谢谢你的建议,我会的!事实上,我也应该可以不用C++11。我经常在集群上运行数字代码,那里的编译器并不是最先进的。也被称为弃用的std::pointer\u to_一元/二元函数
,我们应该让它们独立运行。(他们休息的时间可能已经比不赞成的时间长了。没用的混蛋。)我尝试了一些类似的方法。由于您提到的std::sin问题,它失败了。所以我的问题是如何使用像std::sin这样的函数实现它。GCC错误消息在这里没有太大帮助…@Monkey我省略了这一部分,因为我不知道如何将它添加到您的大方案中:您需要添加一个获取functorF
并初始化成员(可能为其提供一个默认参数,以便它仍能与可默认构造的functor无缝地工作)。