Sign in to follow this  
Endar

std::set complaining about already defined operators

Recommended Posts

Endar    668
I'm having a problem where the compiler is complaining on behalf of std::set about operators that already seem to exist.
1>c:\program files\microsoft visual studio 8\vc\include\functional(143) : error C2678: binary '<' : no operator found which takes a left-hand operand of type 'const cc::Index2d' (or there is no acceptable conversion)
1>        c:\programming\crystal cylinder\index2d.h(134): could be 'bool cc::Index2d::operator <(const cc::Index2d &)'
1>        while trying to match the argument list '(const cc::Index2d, const cc::Index2d)'
1>        c:\program files\microsoft visual studio 8\vc\include\functional(142) : while compiling class template member function 'bool std::less<_Ty>::operator ()(const _Ty &,const _Ty &) const'
1>        with
1>        [
1>            _Ty=cc::Index2d
1>        ]
1>        c:\program files\microsoft visual studio 8\vc\include\set(60) : see reference to class template instantiation 'std::less<_Ty>' being compiled
1>        with
1>        [
1>            _Ty=cc::Index2d
1>        ]
1>        c:\program files\microsoft visual studio 8\vc\include\xtree(26) : see reference to class template instantiation 'std::_Tset_traits<_Kty,_Pr,_Alloc,_Mfl>' being compiled
1>        with
1>        [
1>            _Kty=cc::Index2d,
1>            _Pr=std::less<cc::Index2d>,
1>            _Alloc=std::allocator<cc::Index2d>,
1>            _Mfl=false
1>        ]
1>        c:\program files\microsoft visual studio 8\vc\include\xtree(68) : see reference to class template instantiation 'std::_Tree_nod<_Traits>' being compiled
1>        with
1>        [
1>            _Traits=std::_Tset_traits<cc::Index2d,std::less<cc::Index2d>,std::allocator<cc::Index2d>,false>
1>        ]
1>        c:\program files\microsoft visual studio 8\vc\include\xtree(94) : see reference to class template instantiation 'std::_Tree_ptr<_Traits>' being compiled
1>        with
1>        [
1>            _Traits=std::_Tset_traits<cc::Index2d,std::less<cc::Index2d>,std::allocator<cc::Index2d>,false>
1>        ]
1>        c:\program files\microsoft visual studio 8\vc\include\xtree(112) : see reference to class template instantiation 'std::_Tree_val<_Traits>' being compiled
1>        with
1>        [
1>            _Traits=std::_Tset_traits<cc::Index2d,std::less<cc::Index2d>,std::allocator<cc::Index2d>,false>
1>        ]
1>        c:\program files\microsoft visual studio 8\vc\include\set(69) : see reference to class template instantiation 'std::_Tree<_Traits>' being compiled
1>        with
1>        [
1>            _Traits=std::_Tset_traits<cc::Index2d,std::less<cc::Index2d>,std::allocator<cc::Index2d>,false>
1>        ]
1>        c:\programming\crystal cylinder\cylinder.h(39) : see reference to class template instantiation 'std::set<_Kty>' being compiled
1>        with
1>        [
1>            _Kty=cc::Index2d
1>        ]


I understand the first bit about no '<' operator being defined. Everything else I assume, are errors because of the internal implementation of the std::set, which I don't need to know about.
struct Index2d{

	unsigned int x;
	unsigned int y;

	// Constructor, misc other operators, etc, etc

	/**
	 * Overloaded less than operator
	 * NB. The only reason I have this is because std::set needs it to keep a set ordered.
	 * There isn't really a way to define one index as being 'less' than another, so I'm just basing
	 * it purely on the numerical values of each index component.
	 * \param in The Index2d object to compare to
	 * \return Whether this object is less than the passed object
	 */
	bool operator<(const Index2d& b)
	{
		if( x < b.x )
			return true;
		else if( x == b.x ){
			if( y < b.y )
				return true;
			
			// by this point y == b.y OR y > b.y, same result either way
			return false;
		}

		// by this point, x > b.x
		return false;
	}

};

I really don't understand what the problem is. I attempted defining it as a global operator with arguments (const Index2d&, const Index2d&), but I just got 11 errors, which seemed to have a lot to do with STL containers I wasn't using, and I decided that 1 error was better than 11. What exactly have I missed doing?

Share this post


Link to post
Share on other sites
bubu LV    1436
It is not complaining about already existing operators! Compiler is complaining that no operator is found!:

1>c:\program files\microsoft visual studio 8\vc\include\functional(143) : error C2678: binary '<' : no operator found which takes a left-hand operand of type 'const cc::Index2d' (or there is no acceptable conversion)

It is trying to match following signature for operator <

1> c:\program files\microsoft visual studio 8\vc\include\functional(142) : while compiling class template member function 'bool std::less<_Ty>::operator ()(const _Ty &,const _Ty &) const'
1> with
1> [
1> _Ty=cc::Index2d
1> ]

But you have in your code following operator:

1> c:\programming\crystal cylinder\index2d.h(134): could be 'bool cc::Index2d::operator <(const cc::Index2d &)'

See the difference? (const keyword)

Share this post


Link to post
Share on other sites
Julian90    736
Quote:

I really don't understand what the problem is. I attempted defining it as a global operator with arguments (const Index2d&, const Index2d&), but I just got 11 errors, which seemed to have a lot to do with STL containers I wasn't using, and I decided that 1 error was better than 11.


For binary operators you should prefer where possible:
a) Non member functions (Improves encapsulation)
b) Non member friend functions

This is because member functions dont allow type conversion on the left argument.
Example:

struct my_int
{
my_int(int i): value(i) { }
my_int operator+(const my_int& rhs) const
{ return my_int(value + rhs.value); }
};

int main()
{
my_int i = 5;
// this will work
i + 5;
// this wont work
5 + i;
// both will work with non member functions.
}



If you want to try to get it working as a non member function then post the operator decleration that you had, if it or Index2D is in a namespace then that may have been related to the problem as well.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this