返回迭代器与松耦合 [英] Returning Iterator vs Loose Coupling

查看:132
本文介绍了返回迭代器与松耦合的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个关于我写的数据结构的架构的问题。我正在写一个图像类,我将使用它在一个特定的算法。在此算法中,我需要触摸图像中位于特定边框内的每个像素。我知道这样做的经典方法是两个嵌套的for循环:

  for(int i = ROW_BORDER; i  for(int j = COL_BORDER; j< img-> width  -  COL_BORDER; j ++)
WHATEVER
/ pre>

然而,我被告知在STL的风格,它通常更好的是返回一个迭代器,而不是使用循环如上。这将是很容易得到一个迭代器来看看图像中的每个像素,它甚至可以很容易地纳入边框约束,但我觉得包括边界吹出松耦合出水。



所以,问题是,如果我应该返回一个特殊的边界排除迭代器,使用for循环,还是有一个更好的方式,我没有想过?



只是为了避免像好,只需使用OpenCV或VXL! ,我实际上不是写一个图像类,我正在写一个差异的高斯金字塔用于特征检测器。也就是说,同样的问题也适用,并且比3或4更容易编写两个for循环。

解决方案

可重复使用,我会使用地图功能。

 命名空间your_imaging_lib {

template< typename Fun>
void transform(Image& img,Fun fun){
const size_t width = img.width(),
size = img.height()* img.width
Pixel * p = img.data();
for(size_t s = 0; s!= size; s + = width)
for(size_t x = 0; x!= width; ++ x)
p [x + s] fun(p [x + s]);

}

template< typename Fun>
void generate(Image& img,Fun fun){
const size_t width = img.width(),size = img.height();
Pixel * p = img.data();
for(size_t s = 0,y = 0; s!= size; s + = width,++ y)
for(size_t x = 0; x!= width; ++ x)
p [x + s] = fun(x,y);
}

}

例如,一些系统像x,y在[0..1)。



然后你可以使用这样:

 使用命名空间your_imaging_lib; 
Image i = Image :: FromFile(foobar.png);
map(i,[](Pixel const& p){return Pixel :: Monochrome(p.r());});

  generate(i,[](int x,int y){return(x ^ y)& 0xFF;}); 

如果你需要知道坐标(x和y),我保证这将提供更好的性能



另一方面,迭代器会使用标准算法来使用您的东西,例如 std :: transform ,如果不需要像素位置,并且数据中没有大的间距(间距是为了对齐,通常在图形硬件表面上找到),你可以使它们几乎一样快。


I've got a question about the architecture of a data structure I'm writing. I'm writing an image class, and I'm going to use it in a specific algorithm. In this algorithm, I need to touch every pixel in the image that's within a certain border. The classic way I know to do this is with two nested for loops:

for(int i = ROW_BORDER; i < img->height - ROW_BORDER; i++)
    for(int j = COL_BORDER; j < img->width - COL_BORDER; j++)
        WHATEVER 

However, I've been told that in style of the STL, it is in general better to return an iterator rather than use loops as above. It would be very easy to get an iterator to look at every pixel in the image, and it would even be easy to incorporate the border constraints, but I feel like included the border is blowing loose coupling out of the water.

So, the question is, should I return a special "border-excluding iterator", use the for loops, or is there a better way I haven't thought of?

Just to avoid things like "well, just use OpenCV, or VXL!" , I'm not actually writing an image class, I'm writing a difference-of-gaussian pyramid for use in a feature detector. That said, the same issues apply, and it was simpler to write two for loops than three or four.

解决方案

To have something reusable, I'd go with a map function.

namespace your_imaging_lib {

    template <typename Fun>
    void transform (Image &img, Fun fun) {
        const size_t width = img.width(), 
                     size  = img.height() * img.width();
        Pixel *p = img.data();
        for (size_t s=0; s!=size; s+=width)
        for (size_t x=0; x!=width; ++x)
            p[x + s] = fun (p[x + s]);

    }

    template <typename Fun>
    void generate (Image &img, Fun fun) {
        const size_t width = img.width(), size = img.height();
        Pixel *p = img.data();
        for (size_t s=0, y=0; s!=size; s+=width, ++y)
        for (size_t x=0; x!=width; ++x)
            p[x + s] = fun (x, y);
    }

}

Some refinement needed. E.g., some systems like x, y to be in [0..1).

You can then use this like:

using namespace your_imaging_lib;
Image i = Image::FromFile ("foobar.png");
map (i, [](Pixel const &p) { return Pixel::Monochrome(p.r()); });

or

generate (i, [](int x, int y) { return (x^y) & 0xFF; });

Iff you need knowledge of both coordinates (x and y), I guarantee this will give better performance compared to iterators which need an additional check for each iteration.

Iterators, on the other hand, will make your stuff usable with standard algorithms, like std::transform, and you could make them almost as fast if pixel positions are not needed and you do not have a big pitch in your data (pitch is for alignment, usually found on graphics hardware surfaces).

这篇关于返回迭代器与松耦合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆