Can't compile lambda without "const" in the parameter list - c++

#include <stack>
#include <list>
#include <string>
#include <iostream>
#include <algorithm>
#include <vector>
#include <numeric>
using namespace std;
void biggies(vector<string>& str,vector<string>::size_type sz)
{
sort(str.begin(),str.end());
auto end_unique=unique(str.begin(), str.end());
str.erase(end_unique,str.end());
//When I remove the "const" in the parameter list, the code can't compile
stable_sort(str.begin(), str.end(), [](const string&a,const string&b){return a.size()<b.size();});
auto wc=find_if(str.begin(), str.end(), [sz](string& a){return a.size()>=sz;});
for_each(wc, str.end(), [](string& s){cout<<s<<endl;});
}
int main()
{
vector<string>vec{"11","22","1","1111","2222","2","111","222"};
biggies(vec, 2);
}
I test the code in Xcode 6.4 and Visual Studio 2015 and it turns out that both cannot compile without the "const" in the parameter list. I wonder why the lack of "const" would disrupt the compilation? I'll be very thankful with your answers.

I can't find anything in the standard (N3337) that puts any specific requirements on the parameter types for a comparator passed to sorting-related algorithms. All I can find that kind of hints at why you're having this issue is this:
25.4.2: It is assumed that comp will not apply any non-constant function through the dereferenced
iterator.
It is somewhat indirect, but since it is 'assumed' that your comparator won't apply any non-const function to what's given to you by the algorithm, I guess it's valid that the algorithm pass const objects to it; this is likely the source of your problem.

Related

Using std::vector does not work

Why the following code doesn't compile,
#include <vector>
using std::vector;
vector<int> v; // Error: too few template arguments, expected 2
but the same code with map (and pair, set, ...) instead of vector works?
#include <map>
using std::map;
map<int, int> m; // OK
And also this code works fine:
#include <vector>
using namespace std;
vector<int> v; // OK
I know that constructor of std::vector has two arguments (type and allocator), but why vector behaviour is so different from other containers?
UPD: I'm sorry, this is my mistake. Actually the code does compile, but CLion marks it as an error. So it is CLion's bug.
It is yet not fixed CLion bug: https://youtrack.jetbrains.com/issue/CPP-5758#u=1454575544687.
As a workaround you can try to use libstdc++ instead of libc++, see https://youtrack.jetbrains.com/issue/CPP-5758#comment=27-2389700.

c++ and the type size_type

The following code fragment fails to compile:
#include <vector>
#include <string.h>
#include <cstddef.h>
#include <stddef.h>
using namespace std;
vector<int> list1{1,3,5,7,11};
size_type s1 = list1.size();
I am using the Microsoft Visual Stdio but I would not expect this to be compiler dependent. I believe the problem is that I am failing to include the correct header. What header should I be including?
Bob
size_type is a dependent name of the container you are using. You need
std::vector<int>::size_type
You could use std::size_t as that is what size_type generally boils down to but std::vector<int>::size_type is guaranteed to be correct.
If you are using C++11 or higher then you can forgot about this detail and just use
auto s1 = list1.size();
The compiler will deduce the correct type and if you ever change the container type this line does need to be changed.

C++ unordered map error

I'm trying to declare an unordered map into my program in which I will map them to tokens in another file.
I need a method which returns the Token type found in Token.h (which is an enum class)
What is confusing me is that, since I want to return the mapped Tokens from the unordered_map to the enum class, what should be the return type of the method? Also, it is stating that
error: 'unordered_map' does not name a type
I am rather new to C++ and am still finding it a bit hard in this case how I should declare methods. I've read that the unordered map should be declared INSIDE a method, but since I want the value returned by the map, which should be the return type?
I tried this
Test 1
Token Lexer::getTokenType()
{
unordered_map<string,Token> tokenType;
}
This outputs these errors:
Test 2 I tried this
#include <iostream>
#include <fstream>
#include <string>
#include <stdlib.h>
#include <stdio.h>
#include <sstream>
#include <wctype.h>
#include <map>
#include "lexer.h"
using namespace std;
long Row, Col, Offset;
unordered_map<string, Token> ProtectedWords
{
}
OR
unordered_map<string, Token>::Lexer::getTokenType()
{
}
still yielded the same
Its error:
I know these do sound stupid, but would you mind explain to me please? As in the tutorial I followed many are, yes, called inside a method, but even that did not work
You need to include <unordered_map>.
You'll also need to enable C++11 support, if you haven't already done so: for GCC, make sure the compiler arguments include -std=c++11 (or c++0x if you're using an old compiler).

Accessing second elements of the map with for_each or transform

I'd like to ask you how could I copy all second elements from
map<string, string> myMap
to
deque<string> myDeq
using for_each or transform without creating a functor. I tried it like in this question
transform(myMap.begin(), myMap.end(), back_inserter(myDeq), mem_fun_ref(&map<string, string>::value_type::second));
but it didn't work for me - I got error "Illegal use of this type".
The reason you get the error is because map<string, string>::value_type::second is not a member function. It is just a member variable of the std::pair template struct.
One possible solution without using functors is with the use of lambdas. But it's a C++11 feature so I don't know if that's what you want.
Take a look at the following example
#include <iostream>
#include <map>
#include <deque>
#include <algorithm>
#include <string>
#include <iterator>
using namespace std;
int main()
{
map<string,string> myMap;
deque<string> myDeque;
myMap["key1"]="value1";
myMap["key2"]="value2";
transform(myMap.begin(),myMap.end(),back_inserter(myDeque),[](map<string,string>::value_type p){return p.second;});
copy(myDeque.begin(),myDeque.end(),ostream_iterator<string>(cout,"\n"));
}

STL algorithm function name resolution

I'd expect in the example bellow compiler will fail to compile the code, since it
doesn't know what is "find()", which defined in std namespace in algorithm header.
However this code compiles on RHEL 5.3 with gcc 4.1.2.
What do I miss?
#include <string>
#include <algorithm>
int main()
{
std::string s;
find(s.begin(), s.end(), 'a'); // should not compile
}
This works due to Argument Dependent Lookup. The function-template is searched in the namespace of the arguments types. In this case, the arguments are std::string::iterator, so the function is searched in the namespace std.