sort predicate w lambda = compiler error

Here is some code with the error messages at the end. I can't figure out why I get compiler errors. If I comment out the sort statement, the compile error goes away. I just don't see anything wrong with it: (BTW, I just wanted to get to the lambdas to try it out, so the rest of it is not necessarily the way I'd normally code it up) Oh I'm using free download version of Visual Studio 2013.

Thanks in advance if you can help.

------------------------------

#include "stdafx.h"
#include <iostream>
#include <string>
#include <list>
#include <algorithm>
#include <functional>
using namespace std;

struct name
{
string firstName;
string middleName;
string lastName;

name(string a, string b, string c) : firstName(a), middleName(b), lastName(c)
{

}

void changeName(string a, string b, string c)
{
firstName = a;
middleName = b;
lastName = c;
}

void print()
{
cout << firstName << ", " << middleName << ", " << lastName << "\n";
}
};

int _tmain(int argc, _TCHAR* argv[])
{

list<name> nameList;
name nameObj("john", "t", "Smith");
nameList.push_back(nameObj);

nameObj.changeName("bo", "c", "jackson");
nameList.push_back(nameObj);

nameObj.changeName("Derek", "charles", "mito");
nameList.push_back(nameObj);

nameObj.changeName("Alice", "in", "wonderland");
nameList.push_back(nameObj);

nameObj.changeName("Roberto", "Alonze", "Morris");
nameList.push_back(nameObj);

nameObj.changeName("Xiang", "chi", "Fu");
nameList.push_back(nameObj);


sort(nameList.begin(), nameList.end(), [](const name &a, const name &b)->bool{return a.lastName < b.lastName; });

cout << "\nName list by last name";

for_each(nameList.begin(), nameList.end(), [](const name &in){cout << "\n" << in.firstName << ", " << in.middleName << ", " << in.lastName; });

cout << "\n\nhit enter to exit ";
getline(cin, dummy);
return 0;
}


Error 1 error C2784: 'unknown-type std::operator -(std::move_iterator<_RanIt> &,const std::move_iterator<_RanIt2> &)' : could not deduce template argument for 'std::move_iterator<_RanIt> &' from 'std::_List_iterator<std::_List_val<std::_List_simple_types<name>>>' c:\program files (x86)\microsoft visual studio 12.0\vc\include\algorithm 3157 1 Lambda 1

Error 2 error C2784: 'unknown-type std::operator -(const std::reverse_iterator<_RanIt> &,const std::reverse_iterator<_RanIt2> &)' : could not deduce template argument for 'const std::reverse_iterator<_RanIt> &' from 'std::_List_iterator<std::_List_val<std::_List_simple_types<name>>>' c:\program files (x86)\microsoft visual studio 12.0\vc\include\algorithm 3157 1 Lambda 1

Error 3 error C2784: 'unknown-type std::operator -(const std::_Revranit<_RanIt,_Base> &,const std::_Revranit<_RanIt2,_Base2> &)' : could not deduce template argument for 'const std::_Revranit<_RanIt,_Base> &' from 'std::_List_iterator<std::_List_val<std::_List_simple_types<name>>>' c:\program files (x86)\microsoft visual studio 12.0\vc\include\algorithm 3157 1 Lambda 1

Error 5 error C2780: 'void std::_Sort(_RanIt,_RanIt,_Diff,_Pr)' : expects 4 arguments - 3 provided c:\program files (x86)\microsoft visual studio 12.0\vc\include\algorithm 3157 1 Lambda 1

Error 4 error C2676: binary '-' : 'std::_List_iterator<std::_List_val<std::_List_simple_types<name>>>' does not define this operator or a conversion to a type acceptable to the predefined operator c:\program files (x86)\microsoft visual studio 12.0\vc\include\algorithm 3157 1 Lambda 1


--------------------------------------------------
Try this:

std::sort(nameList.begin(), nameList.end() [&](const name a, const name b)->bool{return a.lastName < b.lastName;});
You cant't use std::sort on a std::list because it takes random access Iterators and a std::list only supplies bidirectional Iterators. Use std::list::sort().
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <iostream>
#include <string>
#include <list>
#include <algorithm>

struct name
{
    std::string firstName;
    std::string middleName;
    std::string lastName;

    name(std::string a, std::string b, std::string c)
        : firstName(a), middleName(b), lastName(c) {}

    void print() const
    { std::cout << firstName << ", " << middleName << ", " << lastName << '\n' ; }
};

//int _tmain(int argc, _TCHAR* argv[])
int main()
{
    // http://www.stroustrup.com/C++11FAQ.html#uniform-init
    // http://www.stroustrup.com/C++11FAQ.html#init-list
    std::list<name> name_list { { "john", "T", "Smith" }, { "Derek", "Charles", "Mito" } } ;

    // http://www.cplusplus.com/reference/list/list/emplace_back/
    name_list.emplace_back( "Alice", "In", "Wonderland" );
    name_list.emplace_back( "Roberto", "Alonze", "Morris" );
    name_list.emplace_back( "Xiang", "chi", "Fu" );

    // http://www.cplusplus.com/reference/list/list/sort/
    name_list.sort( []( const name &a, const name &b ) { return a.lastName < b.lastName; } );

    std::cout << "Name list by last name\n-----------------\n";

    // http://www.stroustrup.com/C++11FAQ.html#for
    for( const name& n : name_list ) n.print() ;

    std::cout << "\n\nhit enter to exit ";
    std::cin.get() ;
}

http://coliru.stacked-crooked.com/a/ea98c7d300e9bba4
using

std::sort(nameList.begin(), nameList.end(), [&](const name a, const name b)->bool{return a.lastName < b.lastName; });

I get compiler error:


Error 1 error C2784: 'unknown-type std::operator -(std::move_iterator<_RanIt> &,const std::move_iterator<_RanIt2> &)' : could not deduce template argument for 'std::move_iterator<_RanIt> &' from 'std::_List_iterator<std::_List_val<std::_List_simple_types<name>>>' c:\program files (x86)\microsoft visual studio 12.0\vc\include\algorithm 3157 1 Lambda 1

Error 2 error C2784: 'unknown-type std::operator -(const std::reverse_iterator<_RanIt> &,const std::reverse_iterator<_RanIt2> &)' : could not deduce template argument for 'const std::reverse_iterator<_RanIt> &' from 'std::_List_iterator<std::_List_val<std::_List_simple_types<name>>>' c:\program files (x86)\microsoft visual studio 12.0\vc\include\algorithm 3157 1 Lambda 1

Error 3 error C2784: 'unknown-type std::operator -(const std::_Revranit<_RanIt,_Base> &,const std::_Revranit<_RanIt2,_Base2> &)' : could not deduce template argument for 'const std::_Revranit<_RanIt,_Base> &' from 'std::_List_iterator<std::_List_val<std::_List_simple_types<name>>>' c:\program files (x86)\microsoft visual studio 12.0\vc\include\algorithm 3157 1 Lambda 1

Error 5 error C2780: 'void std::_Sort(_RanIt,_RanIt,_Diff,_Pr)' : expects 4 arguments - 3 provided c:\program files (x86)\microsoft visual studio 12.0\vc\include\algorithm 3157 1 Lambda 1

Error 4 error C2676: binary '-' : 'std::_List_iterator<std::_List_val<std::_List_simple_types<name>>>' does not define this operator or a conversion to a type acceptable to the predefined operator c:\program files (x86)\microsoft visual studio 12.0\vc\include\algorithm 3157 1 Lambda 1

could you elaborate on the code? I feel like I just need 2 args to compare, why do I need to capture any var refs in the enclosing scope?

--------------------------------

When I use the std::List::sort, should it be like this with a lambda?

nameList.sort( [] (const name &a, const name &b)->bool{return a.lastName < b.lastName; });

This compiles but i get a really weird sort - What is going on behind the scenes? Results:

Name list by last name
Xiang, chi, Fu
Roberto, Alonze, Morris
john, t, Smith
bo, c, jackson
Derek, charles, mito
Alice, in, wonderland

Thanks guys
> I feel like I just need 2 args to compare, why do I need to capture any var refs in the enclosing scope?

You do not need to capture anything.


> When I use the std::List::sort, should it be like this with a lambda?
> nameList.sort( [] (const name &a, const name &b)->bool{return a.lastName < b.lastName; });

Yes. You can omit the -> bool, it is inferred.


> but i get a really weird sort - What is going on behind the scenes?

There is nothing weird about it; default std::string comparisons are case-sensitive.
:) so much of the stuff I type in during the day has no case-sensitivity. I completely forgot about it. Thanks!
Why are you using a linked list here? Most likely it is making your code slower rather than faster.
Topic archived. No new replies allowed.