Skip to main content
GameDev.net gamedev.net
🔒 Locked 🎮 Unity

STL binary function

Started by Graham11 May 19, 2006 at 10:27 AM 6 replies 1.4k views
Original Post
Graham11
Graham11
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;
}

kuphryn
kuphryn
argument TReal
return result_type

what Lenght()?

Kuphryn
Graham11
Graham11
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 , 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
Graham11
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
Emmanuel Deloget
Emmanuel Deloget
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 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,
Zahlman
Zahlman
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.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.