• Advertisement
Sign in to follow this  

std::set complaining about already defined operators

This topic is 3940 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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
Advertisement
bool operator<(const Index2d& b)
Should be:
bool operator<(const Index2d& b) const

Share this post


Link to post
Share on other sites
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
Thanks guys, I knew it was going to be something small like that.

Share this post


Link to post
Share on other sites
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
Sign in to follow this  

  • Advertisement