簡體   English   中英

將仿函數作為C ++模板參數傳遞

[英]Passing a functor as C++ template parameter

作為我個人啟蒙的練習,我用表達模板實現了矢量數學。 我想實現一些操作,將相同的一元函數應用於向量表達式的所有元素。 到目前為止,我這樣做了。

我的基本載體表達模板是這樣實現的

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];
};

假設我想將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]); }
};

問題=>如果我想添加更多功能,我會為每個函數(如cos,sqrt,fabs等)復制粘貼我為sin函數所做的操作。 我怎么能避免這種復制粘貼? 我嘗試了一些東西,並發現我的模板效率仍然很低。 沒有提升允許^^

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;
};

除了pmr的答案之外 ,標准的<cmath>函數不是仿函數,所以你不能直接使用它們來指定類的唯一特化 - 即你不會為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();
}

這樣你就可以像普通仿函數一樣使用它們作為模板參數

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM