STL binary function

Started by
6 comments, last by Zahlman 17 years, 11 months ago
Hi all, I'm having a little problem using the STL function 'adjacent_difference' with my own std::binary_function-derived function. I've created a simple main.cpp (below) to show the problem. When I hit compile I get: error C2440: '=' : cannot convert from 'std::iterator_traits<_Iter>::value_type' to 'std::allocator<_Ty>::value_type' Does anyone know, where have I erred? All the best, Graham

#include <iostream>
#include <deque>
#include <vector>
#include <numeric>
#include <functional>

#include <Wm3Vector3.h>	// http://www.geometrictools.com/Foundation/Math/Wm3Vector3.h

template < class TReal >
class Vec3DistanceBetween : public std::binary_function< Wm3::Vector3< TReal >, Wm3::Vector3< TReal >, TReal >
{
public:
	result_type operator()( const first_argument_type &arg1, const second_argument_type &arg2 ) const
	{
		return ( arg2 - arg1 ).Length();
	}
};

int main()
{
	std::vector< float >::iterator	Iter;
	std::vector< Wm3::Vector3< float > > in;
	std::vector< float > out;
	adjacent_difference( in.begin(), in.end(), out.begin(), Vec3DistanceBetween< float >() );
	return 1;
}

Advertisement
argument TReal
return result_type

what Lenght()?

Kuphryn
Length returns a templated Real type; the length of a vector. I tried casting the result to 'result_type', but that didn't help ( return (result_type)( arg2 - arg1 ).Length(); )

I looked in <numeric>, and it seems like the line:
for (*_Dest = _Val; ++_First != _Last; )
in _Adjacent_difference is involved, due to it trying to assign *_Dest (which is a Real) with _Val (which is a Vector3). I don't know how to avoid this though; my binary_function's first_argument and second_argument are of different type to my result_type.

Thanks,
Graham
the problem could also be in the Length() implementation of yours. Does it work with a difference of two vectors, each being const? When you think "hey! that's the same type! Why isn't there a conversion?".. often const is the "problem".
Make sure your implementation of Length() is const correct.. just a guess, though. You might want to post your Length() method, if you are not sure.

cheers,
simon
The problem is probably that adjacent_difference needs to copy the first input element to the output, but has no way to convert a vector to float.
To the first anonymous comment:
The minus operator declaration looks like this:
Vector3 operator- (const Vector3& rkV) const;

and the Length() method is declared:
Real Length () const;

To the second anonymous comment:
This does look like the problem, but how should adjacent_difference() handle such a common situation? I just don't know.

By the way, I'm using Visual Studio 2003 7.1. Maybe I should try another STL implementation such as STLport?

Any suggestions are most welcome.

Ta,
Graham
Quote:Original post by Graham11
To the first anonymous comment:
The minus operator declaration looks like this:
Vector3 operator- (const Vector3& rkV) const;

and the Length() method is declared:
Real Length () const;

To the second anonymous comment:
This does look like the problem, but how should adjacent_difference() handle such a common situation? I just don't know.

By the way, I'm using Visual Studio 2003 7.1. Maybe I should try another STL implementation such as STLport?

Any suggestions are most welcome.

Ta,
Graham


The error you get is correct. From sgi's description of adjacent_difference:
Quote:
Adjacent_difference calculates the differences of adjacent elements in the range [first, last). This is, *first is assigned to *result [1], and, for each iterator i in the range [first + 1, last), the difference of *i and *(i - 1) is assigned to *(result + (i - first)). [2]

(Emphasis is mine).
The type requirements specifically says:
Quote:
InputIterators value type is convertible to a type in OutputIterator's set of value types.

This is obviously not your case (you have no way to convert a Wm::Vector<float> to a float).

For more information here is what the standard says on this issue (26.4.4):
Quote:Effect: (...) result get the value of *first.
Complexity: exactly (last - first) - 1 application of binary_op

This leads to the same type requirements as in the sgi's explaination.

I'm not sure how to implement what you want. I guess you'll have to implement your own function (not so difficult [smile]).

Regards,
He presumably wants the "differences" applied between adjacent pairs of values.

I *think* that binary std::transform can do this for you:

transform(in.begin(), in.end() - 1, in.begin() + 1, out.begin(),          Vec3DistanceBetween< float >());


The SGI doc mentions that the output range can overlap the input range, but seems to be only talking about the unary version, and doesn't say anything about two input ranges overlapping. But as long as your operator is non-mutating, I don't see how it could cause a problem.

This topic is closed to new replies.

Advertisement