使用boost :: bind()在std :: min_element()的自定义函数中填充结构

时间:2016-01-01 10:04:50

标签: c++ c++11 boost vector iterator

尝试在我的矢量上保存一次迭代。

我有vector<T>我需要在向量中找到最小元素。

我正在使用std::min_element。现在需要创建一个自定义结构,其中包含<T>加上一些额外的元素,即时计算。

所以我尝试使用boost::bind()这样的函数:

std::vector<MyStruct> myStructObj;
typename std::vector< T >::iterator it = std::min_element(V.begin(), V.end(), boost::bind(BuildStructAndFindMin, myStructObj, _1, _2));

但是我应该如何定义BuildStructAndFindMin函数?直到现在,我从来不需要创建这样的自定义功能。

  1. _1和_2表示两个参考对象到V的内容但是哪一个是最少的?我的意思是:std::min_element()'s定义将迭代一个向量。对于第一次调用,它只会发送前两个元素。对于第二次调用,将发送来自vector和last_found_min元素的第三个元素。哪个,_1或_2将成为last_found_min? 如何返回迭代器?我的模糊草图是这样的:

    std::vector< T >::iterator BuildStructAndFindMin (std::vector<MyStruct>& myStructObj, const T &a, const T &b)
    {
        if(<a_min_condition>) // I am aware of this if statement. Just assume it to be a<b
        {
            // the point which is greater - create a struct object for that
            // and push_back in myStructObj
    
            return //what?;
        }
        else
        {
            // the point which is greater - create a struct object for that
            // and push_back in myStructObj
    
            return //what?
        }
    }
    
  2. 在调用此函数后,我将有一个min_element,但它不会出现在myStructObj中。所以我会在开头插入它。

    这一戏剧的重点是保存一次迭代。

    最简单的方法是:迭代一个向量并构建一个结构。然后拨打std::min_element()。但不知何故,我正在争夺几纳秒,在这种情况下,时间就是金钱。

2 个答案:

答案 0 :(得分:1)

std::min_element的第三个参数可以是这样的类:

struct myclass { 
    bool operator() (int i,int j) { return i<j; }
};

在comperator类中,您可以存储所需的任何信息,并且可以实现所需的任何逻辑。如果有必要,你甚至可以将boost::bind之类的东西作为参数传递给它的构造函数。

template< typename T, typename TSTRUCT, typename TBIND >
struct MyCompare
{
    MyCompare( TSTRUCT &myStruct, T &ref1, T &ref2, TBIND bind )
        : _myStruct( myStruct )
        , _1( ref1 )
        , _2( ref2 )
        , _bind( bind )
    {}
    bool operator()( const T &a, const T &b )
    {
        // enter your code her
        return ...;
    }

    TSTRUCT &_myStruct;
    T &_1;
    T &_2;
    TBIND &_bind; 
};

template< typename T > 
struct MyStruct
{
    std::vector< T > V;
    T obj1;
    T obj2;
  typename std::vector< T >::iterator it = std::min_element(V.begin(), V.end(), MyCompare<T,MyStruct>( *this, obj1, obj2, boost::bind( ... what ever ... ) ) );
};

答案 1 :(得分:1)

我发现一个简单而优雅的解决方案是重载<运算符。假设您的MyStruct结构定义如下。

struct MyStruct
{
    std::string str;
    int num;

    MyStruct(int initial_value)
        : num(initial_value)
    {
    }

    bool operator<(const MyStruct& other)
    {
        return num < other.num;
    }
};

所以你有几个成员,有一个构造函数,这都是标准的东西。但是,请注意operator<函数,如果true MyStruct被认为“小于”this MyStruct,那么它只会返回otherfalse除此以外。现在,您可以在MyStruct中使用std::min_element,就像使用整数一样。看看:

int main()
{
    std::vector<MyStruct> objects = {10, 20, 15, 2, 25, 5, 30};
    std::vector<MyStruct>::iterator minval = std::min_element(objects.begin(), objects.end());

    std::cout << "Minimum value is " << minval->num << std::endl;

    return 0;
}

此代码打印出2作为最小值。现在,您可能已经注意到使用C ++ 11初始化列表。在这种情况下,此语法有效,因为在初始化列表中传递的值可以提供给MyStruct的构造函数。我会让你初始化MyStruct s的向量然而你喜欢但我必须为这个例子提出一个完整的定义,但这里的重点是通过重载<运算符,你可以MyStruct。

编辑:

我忘了提及,这个解决方案当然只有你能负担得起改变你的类的公共接口以支持std::min_element运算符重载。我想你可能有理由不能这样做。