Watch, Follow, &
Connect with Us

Please visit our new home
community.embarcadero.com.


Welcome, Guest
Guest Settings
Help

Thread: std::less doesn't recognize overloaded operator< in Clang



Permlink Replies: 3 - Last Post: Apr 2, 2018 10:06 AM Last Post By: Remy Lebeau (Te... Threads: [ Previous | Next ]
Dean Clark

Posts: 50
Registered: 6/12/08
std::less doesn't recognize overloaded operator< in Clang
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 31, 2018 4:15 PM
This is probably something new in the standard. The following program won't compile in the Clang 32-bit mode, but compiles and links using the classic compiler:
#pragma hdrstop
#pragma argsused
 
#ifdef _WIN32
#include <tchar.h>
#else
  typedef char _TCHAR;
  #define _tmain main
#endif
 
#include <stdio.h>
#include <complex>
#include <vector>
#include <algorithm>
 
typedef std::complex<double> Complex;
 
bool operator<(const Complex & lhs, const Complex & rhs)
{
	return lhs.real() < rhs.real();
}
 
void doSort()
{
	std::vector<Complex> vc;
	std::sort(vc.begin(), vc.end());
}
 
int _tmain(int argc, _TCHAR* argv[])
{
	doSort();
	return 0;
}

The errors are:
[bcc32c Error] algorithm(3077): no matching function for call to object of type 'std::less<void>'
  algorithm(3094): in instantiation of function template specialization 'std::_Med3<std::complex<double> *, std::less<void> >' requested here
  algorithm(3109): in instantiation of function template specialization 'std::_Median<std::complex<double> *, std::less<void> >' requested here
  algorithm(3171): in instantiation of function template specialization 'std::_Unguarded_partition<std::complex<double> *, std::less<void> >' requested here
  algorithm(3201): in instantiation of function template specialization 'std::_Sort<std::complex<double> *, int, std::less<void> >' requested here
  algorithm(3208): in instantiation of function template specialization 'std::sort<std::_Vector_iterator<std::_Vector_val<std::_Simple_types<std::complex<double> > > >, std::less<void> >' requested here
  File4.cpp(26): in instantiation of function template specialization 'std::sort<std::_Vector_iterator<std::_Vector_val<std::_Simple_types<std::complex<double> > > > >' requested here
  xstddef(339): candidate template ignored: substitution failure [with _Ty1 = std::complex<double> &, _Ty2 = std::complex<double> &]: invalid operands to binary expression ('std::complex<double>' and 'std::complex<double>')


We get the same errors for any algorithm that relies on std::less, like lower_bound, min_element, and sets. Is this behavior per C++11 or C++14? What do we have to do to get std::less to use the operator< for the Complex type?

Thanks.
Alex Belo

Posts: 626
Registered: 10/8/06
Re: std::less doesn't recognize overloaded operator< in Clang
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 31, 2018 10:54 PM   in response to: Dean Clark in response to: Dean Clark
Dean Clark wrote:

typedef std::complex<double> Complex;

Try add the operator to std:

namespace std
{

bool operator<(const Complex & lhs, const Complex & rhs)
{
return lhs.real() < rhs.real();
}

}

--
Alex
Fraser Ross

Posts: 36
Registered: 1/15/99
Re: std::less doesn't recognize overloaded operator< in Clang
Click to report abuse...   Click to reply to this thread Reply
  Posted: Apr 2, 2018 2:37 AM   in response to: Dean Clark in response to: Dean Clark
If it makes sense to define operator< as you do then why does the
standard not have it defined? I think you would be better with a named
functor to show that using < is not ordinary. I don't think you can put
things in namespace std as Alex suggested because it is forbidden by the
standard unless it is a template specialisation.

Fraser.
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: std::less doesn't recognize overloaded operator< in Clang
Click to report abuse...   Click to reply to this thread Reply
  Posted: Apr 2, 2018 10:06 AM   in response to: Dean Clark in response to: Dean Clark
Dean Clark wrote:

This is probably something new in the standard. The following
program won't compile in the Clang 32-bit mode, but compiles and
links using the classic compiler:

Your same question on StackOverflow was answered yesterday:

https://stackoverflow.com/questions/49593048/

All of the types and templates involved - std::vector, std::complex,
std::sort, and std::less - are members of namespace std. There is
nothing in the ADL rules that would cause a lookup in the global
namespace, as that namespace is not involved. Especially not as the
namespace std contains lots of operator< (just not the one needed here).

On the other hand it is not really a very good idea to overload
comparisons for types that has no inherent order, like complex numbers.
They are two-dimensional and not generally fit for a linear sort.

You "trick" (not really a trick) of using an explicit functor for the
sort order is the correct way to handle this. So just do that.

--
Remy Lebeau (TeamB)
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02