-2

I want to do a for loop on values of a std::map called ORIGIN shown below from a lower value to the upper value: I need to overload the < operator in order to do it.

myclass
{
    typedef std::vector<tactics*> origin_of_tactics;
    typedef map<float, origin_of_tactics, CompareFloat> ::iterator iter_type;
    iter_type it;
    map<float, origin_of_tactics, CompareFloat> ORIGIN;


    for (it = ORIGIN.find(low_value_in_bar); it <= ORIGIN.find(high_value_in_bar); it++)
    {

    }

} // end of myclass

I saw an example for overloading an operator and I tried to change it but I´m not sure how to use it in my class. and if its the correct way to do it:

class Complex
{
    public:
        typedef std::vector<tactics*> origin_of_tactics;
        typedef map<float, origin_of_tactics, CompareFloat>::iterator iter_type;
        bool Complex::operator <(const iter_type &other);
        Complex(iter_type value) : it1(value)
        {};
        bool operator <(const Complex &other);

    private:
        iter_type it1;

};
bool Complex::operator <(const iter_type &other)
{
    if ((it1->first) < (other->first))
    {
        return TRUE;
    }
    else
    {
        return FALSE;
    }
}

How to do it? and how to write it in a general way for any type of MAP iterator < comparison? Thanks

4

3 回答 3

0

这本质上是一条评论,但我希望代码可读。

myclass
{
    typedef std::vector<tactics*> origin_of_tactics;
    typedef map<float, origin_of_tactics, CompareFloat> ::iterator iter_type;
    iter_type it;
    map<float, origin_of_tactics, CompareFloat> ORIGIN;


    for (it = ORIGIN.find(low_value_in_bar); it <= ORIGIN.find(high_value_in_bar); it++)
    {
    }
} // end of myclass

你应该先清理一下:

class myclass
{
public:
    typedef std::vector<tactics*> origin_of_tactics;
    typedef map<float, origin_of_tactics> origins;

    origins ORIGIN;
    // Do NOT store the iterator *value* as a class instance variable
    // it will burn you with fire at this stage in learning C++.
    // The typedef is a good idea for when you have to explicitly state
    // the type, especially if you don't have access to C++11s "auto".
    typedef origins::iterator origin_iter;

    // assuming you want to specify a subset of the values.
    void somefunction(float low_value_in_bar, float high_value_in_bar)
    {
        auto start = ORIGIN.lower_bound(low_value_in_bar);
        auto end   = ORIGIN.upper_bound(high_value_in_bar);
        for (auto it = start; it != end; ++it)
        {
            ....
        }
    }

    // otherwise, since you're using map and it's an ordered container
    void somefunction()
    {
        for (auto it = ORIGIN.begin(); it != ORIGIN.end(); ++it)
        {
            ....
        }
    }

    // or, using new C++11 for
        for (auto& oot : ORIGIN)
        {
           // (oot is of type origin_of_tactics)
        }
} // end of myclass

您不需要重载 operator< 因为它以标准类型为键。

您问题中的代码使您看起来好像将迭代器保留在类成员变量中,而不是作为函数的局部变量。尽量避免这种情况(成员变量迭代器):它会咬你一口,因为迭代器是具有有限生命周期的复杂类型。将它们的定义保持在本地使用可以更容易地追踪它们变得无效的原因。始终将迭代器视为临时的和瞬态的。

std::vector<int> v = { 5, 3, 1 };
auto it = v.begin();
cout << "*it = " << *it << endl;
...
v.push_back(10);
// vector just got bigger and is no-longer in the same location,
// but "it" still points to the old location.
v[0] = 90;
cout << "*it = " << *it << endl; // probably crashes, but won't print 90.

“auto”关键字是一个新的 C++11 关键字,它表示“弄清楚这对我来说应该是什么”,可以在局部变量声明中使用:

std::map<std::string, std::vector<std::array<int, 5> > foo;
std::map<std::string, std::vector<std::array<int, 5> >::iterator it = foo.begin();

可以替换为

std::map<std::string, std::vector<std::array<int, 5> > foo;
auto it = foo.begin();

请参阅http://en.cppreference.com/w/cpp/keyword/auto

于 2013-06-02T18:55:16.243 回答
0

首先,您的比较运算符应该比较 的两个实例Complex,可以写成:

bool Complex::operator<(const Complex&  other) {
    return (this->it1->first) < (other.it1->first);
}  

其次,你似乎不需要那个操作员来做你想做的事。a 的元素已经使用比较器按键std::map<float, origin_of_tactics, CompareFloat>排序(如果未指定,则为默认值)。floatCompareFloatoperator<

您可以像这样遍历始终排序的值:

map<float, origin_of_tactics, CompareFloat> origin;
for (iter_type it = origin.begin(); it != origin.end(); ++it)
{
    ...
}

如果你想遍历地图索引的一个子集,你可以使用std::map::lower_boundand std::map::upper_bound

float beginIndex, endIndex;
iter_type begin = origin.lower_bound(beginIndex);
iter_type end = origin.upper_bound(endIndex);
for (iter_type it = begin; it == end; ++it)
{
    ...
}
于 2013-06-02T17:50:45.060 回答
0

这是错误的:

bool Complex::operator <(const iter_type &other);
// ...
bool Complex::operator <(const iter_type &other);

第一个问题是您尝试对函数进行两次原型设计。Complex::另一个问题是,当您在类中时,声明成员函数时不需要。和第二个一起去吧。

zakinster 的回答涵盖了其余部分。

于 2013-06-02T17:52:15.917 回答