The error points out that your program tried to access a std::vector by an index larger than the size of the container. The cause might not be quick to locate, but I would suggest you take it step by step. Given the size of your main function, it would also help to refactor the code a bit where feasible and limit indentation levels.

Thanks a lot to everybody who replied. It was a problem with one of the for-statements. Also thanks a lot for the tips.. I really appreciate it!

Adrian, thanks a lot for telling me about range based for-loops, I never knew about them! But can you explain why in (const& t : terms) const auto& is used instead of "auto"? (I don't know about pointers). Why is const identifier used?

Also I have seen people using auto&& instead of just auto. And you used auto& What's the difference?

Adrian, thanks a lot for telling me about range based for-loops, I never knew about them! But can you explain why in (const& t : terms) const auto& is used instead of "auto"? (I don't know about pointers). Why is const identifier used?

If you just used auto, you would be making a copy of the corresponding element on each iteration. That is a rather unnecessary copy, that's why you would use const auto& so that the identifier would be a const lvalue reference to the corresponding element, hence avoiding the copies.

Originally Posted by Nwb

Also I have seen people using auto&& instead of just auto. And you used auto& What's the difference?

auto&& would specify that the identifier would be a universal reference to the corresponding element that will behave as an lvalue reference in this case, i.e., if you do make a modification in the loop body, it will affect the corresponding element itself.

Originally Posted by Nwb

Also I casted terms.size to int because the compiler told me that there was a mismatch of data-types..

size() return a size_type (as in std::vector<std::string>::size_type), which is an unsigned integer type, but int is a signed integer type. This can be problematic, hence the warning. As Adrian mentioned, the right approach was to use size_type to begin with, whether it be by spelling it out or by other means, e.g.,

Code:

for (decltype(terms.size()) i = 0; i < terms.size(); ++i)

Originally Posted by Bjarne Stroustrup (2000-10-14)

I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.

If you just used auto, you would be making a copy of the corresponding element on each iteration. That is a rather unnecessary copy, that's why you would use const auto& so that the identifier would be a const lvalue reference to the corresponding element, hence avoiding the copies.

auto&& would specify that the identifier would be a universal reference to the corresponding element that will behave as an lvalue reference in this case, i.e., if you do make a modification in the loop body, it will affect the corresponding element itself.

size() return a size_type (as in std::vector<std::string>::size_type), which is an unsigned integer type, but int is a signed integer type. This can be problematic, hence the warning. As Adrian mentioned, the right approach was to use size_type to begin with, whether it be by spelling it out or by other means, e.g.,

The type for the iterator is probably not correct, but whatever term's type is, you'd just put that in front of ::reverse_iterator (if you want to write it).
Of course other loops you could make are going to be pretty similar. The most different it could get is range-for.

Code:

for (auto term : terms) // assign terms[0], terms[1], etc to term and go

The type for the iterator is probably not correct, but whatever term's type is, you'd just put that in front of ::reverse_iterator (if you want to write it).
Of course other loops you could make are going to be pretty similar. The most different it could get is range-for.

Code:

for (auto term : terms) // assign terms[0], terms[1], etc to term and go

Your first example gives the following error:

Code:

for (auto it = factors.rbegin(); *it != factors.rend(); ++it)

error: binary '!=': no operator found which takes a left-hand operand of type 'std::vector<float,std::allocator<_Ty>>'(or there is no acceptable conversion)

I notice that * is the fault here. Anyways why are we using a rbegin and rend instead of a regular begin and end?

I get the errors:
-> 'y': undeclared identifier (idk why)
-> binary '[': no operator found which takes a right-hand operand of type 'const std::vector<float, std::allocator<_Ty>>'(or there is no acceptable conversion)
-> no operator "[]" matches these operands

So const auto& is the best? When is auto&& used over const auto&?

Also is using .begin() and .end() more efficient than using [0] and .size()?

error: binary '!=': no operator found which takes a left-hand operand of type 'std::vector<float,std::allocator<_Ty>>'(or there is no acceptable conversion)

I notice that * is the fault here.

My bad. Your analysis is correct, however.

Anyways why are we using a rbegin and rend instead of a regular begin and end?

I got the idea from laserlight, who posted a loop going in reverse.

Originally Posted by laserlight

As Adrian mentioned, the right approach was to use size_type to begin with, whether it be by spelling it out or by other means, e.g.,

Code:

for (decltype(terms.size()) i = 0; i < terms.size(); ++i)

Laserlight's loop uses subscripts and goes in reverse, my loop uses iterators and goes in reverse. ::rbegin() and ::rend() are the correct functions to call in order to write that loop. I probably should have made it clear whose example I was using. I'm sorry I didn't.

Do you need an rvalue or not? Read laserlight's comment again and see if you can glean what auto&& means. If you need what auto&& does, then it's the best. If not then there's nothing wrong with something else.

Also is using .begin() and .end() more efficient than using [0] and .size()?

I think it comes down to personal preference more than anything, when you get to make a choice. In reality, you probably won't have a choice most of the time because there is another function you want to call that needs a certain set of arguments, and it is clear whether you should use iterators or subscripts. For example, standard algorithms always want to use iterators.

I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.