0

Image<unsigned>画像を配列として保存し、またはなどの要素のタイプに基づいてテンプレート化していますImage<float>。多くの場合、これらの画像に対して操作を実行する必要があります。たとえば、2つの画像を追加したり、画像を(要素ごとに)正方形にしたりする必要がある場合があります。すべての操作は要素ごとです。私は次のようなことを書くことにできるだけ近づきたいです:

float Add(float a, float b) { return a+b; }
Image<float> result = Add(img1, img2);

そしてさらに良いことに、

complex ComplexCombine(float a, float b) { return complex(a, b); }
Image<complex> result = ComplexCombine(img1, img2);

また

struct FindMax {
    unsigned currentMax;
    FindMax(): currentMax(0) {}
    void operator(unsigned a) { if(a > currentMax) currentMax = a; }
};

FindMax findMax;
findMax(img);
findMax.currentMax;  // now contains the maximum value of 'img'

今、私は明らかにそれを正確に行うことはできません。私は私が呼ぶことができるように何かを書いた:

Image<float> result = Apply(img1, img2, Add);

しかし、渡された関数/関数オブジェクトの戻り型を検出するための一般的な方法を理解できないようです。そのため、ComplexCombine上記の例は出ています。また、渡したい引数の数ごとに新しいものを作成する必要があります(これは避けられないようです)。

これを実現する方法について何か考えはありますか(ボイラープレートコードをできるだけ少なくして)?

4

2 に答える 2

3

これが、STLのunary_function、binary_functionなどの型がresult_typetypedefsを持っている理由です。std :: ptr_funを使用する場合は、Applyでこれを利用できます。

例えば

template<typename Func, typename Arg, typename Result = Func::result_type>
Image<Result> Apply(Arg a1, Arg a2, Func f) {
        return Image<Result>(f(a1,a2));
}

そして、やります、

Apply(img1, img2, std::ptr_fun(&Add));

わかりました、あなたは私を捕まえました、私はそれをテストしませんでした。それでも可能ですが、STL機能の一部を直接使用できなくても作業が増える

#include <iostream>

template<typename T>
struct Image {
  T val_;
  Image(const T& val) : val_(val) {}
};

template<typename Arg1, typename Arg2, typename Result>
struct image_fun_adapter {
  Result (*f)(Arg1, Arg2);
  Image<Result> operator()(const Image<Arg1>& a1, const Image<Arg2>& a2) {
    return Image<Result>(f(a1.val_, a2.val_));
  }
};

template<typename Arg1, typename Arg2, typename Result>
image_fun_adapter<Arg1,Arg2,Result> image_fun_ptr(Result (*f)(Arg1,Arg2)) {
  image_fun_adapter<Arg1,Arg2,Result> rv;
  rv.f = f;
  return rv;
}

float Add(float a, float b) { return a + b; }

int main() {
  Image<float> a(1.0);
  Image<float> b(12.5);
  // this is the cute bit:
  Image<float> c = image_fun_ptr(&Add)(a,b);

  std::cout << c.val_ << std::endl;
  return 0;
}
于 2009-02-26T03:05:47.533 に答える
1

テンプレート特化!

template<typename T>
T Add(const T &left, const T &right)
{
    return left + right;
}

template<typename T>
struct AddTwo
{
    T operator()(const T &left, const T &right)
    {
        return Add(left, right);
    }
};

// something like this (not exactly sure)
template<std::vector<typename V>>
std::vector<V> Add(const std::vector<V> &left, const std::vector<V> &right)
{
    assert(left.size() == right.size());

    std::vector ret(left.size());

    std::transform(left.const_begin(), left.const_end(), right.const_begin(), ret.begin(), AddTwo());

    return ret;
}
于 2009-02-26T03:18:13.963 に答える