std::max_element compile error, C++ - c++

Please see the following 2 examples:
#include <iostream>
#include <algorithm>
#include <vector>
int main()
{
int n;
std::cin>>n;
std::vector<int> V(n);
// some initialization here
int max = *max_element(&V[0], &V[0]+n);
}
This gives the following compiling error:
error C3861: 'max_element': identifier not found
But when I replace the call of *max_element(&V[0], &V[0]+n); to *max_element(V.begin(), V.end()); it does compile:
#include <iostream>
#include <algorithm>
#include <vector>
int main()
{
int n;
std::cin>>n;
std::vector<int> V(n);
// some initialization here
int max =*max_element(V.begin(), V.end());
}
Could somebody explain me why the two are different?

This is due to argument dependant lookup (aka ADL).
Since max_element is defined in the namespace ::std, you should really write std::max_element everywhere. But, when you use it in its second form
max_element(V.begin(), V.end());
since V.begin() and V.begin() have type defined itself in ::std, ADL kicks in and finds std::max_element.

Related

Xcode C++ Vectors: Implicit instantiation of undefined template

I ran this code on a different IDE and it was successful. For some reason I get the above error message on Xcode. I assume I'm missing a header of some kind, but I'm not sure which one.
#include <iostream>
#include <limits>
#include <string>
#include <vector>
int main() {
vector<string> listRestaurants; // error: Implicit instantiation of undefined template
return 0;
}
Xcode 10.2.1 was showing me the error
Implicit instantiation of undefined template 'std::__1::vector<std::__1::basic_string<char>, std::__1::allocator<std::__1::basic_string<char> > >'.
#include <iostream>
#include <vector>
int main(int argc, const char * argv[]) {
std::vector<std::string> listRestaurants;
....
return 0;
}
Fixed my issue.
If adding std:: is not the issue for you, then check if you have #include <vector>. That fixed the issue for me.
Didn't realize that #include <vector> is required. I thought it was part of standard library template; I ran this code in VSCODE IDE and it worked fine for me
#include <iostream>
#include <vector>
using namespace std;
int main()
{
uint_least8_t i; // trying to be conscious of the size of the int
vector<int> vect;
for(i = 0; i < 5; ++i)
{
vect.push_back(i);
}
for(auto i : vect)
{
cout << i << endl;
}
return 0;
}
From the comments:
The std namespace houses both of those templates. Change vector to std::vector, and string to std::string. – WhozCraig
the vector and string were placed in the namespace std
using namespace std;

cant use begin() for array in c++

I am using g++ 7.1.0, yet using begin() with array as an argument throws an error. My code is
#include <iostream>
#include<algorithm>
using namespace std;
int main()
{
int n;
cin>>n;
int a[n];
for(int i = 0; i < n; i++) {
cin>>a[i];
}
sort(begin(a), end(a));
return 0;
}
It says
no matching function for call to 'begin(int [n])'
int a[n]; is invalid statement in C++. C++ doesn't allow variable length array. It is allowed only in C since C99 standard. If you need dynamic array, you should be using std::vector 99% of the time in C++.
You can do this:
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
int main() {
std::cout<<"Enter size of array\n";
int size;
std::cin>>size;
std::vector<int> v(size);
std::cout<<"Enter "<<size<< " elements\n";
for(size_t i=0;i<v.size();++i)
std::cin>>v[i];
std::sort(v.begin(),v.end());
std::cout<<"Sorted elements are: \n";
for(const auto& i : v)
std::cout<<i<<' ';
}
See live demo here.
#include <iterator>
<algorithm> is the wrong header for begin(), end(), and, well, all the iteration functions.
Also, for the iteration functions to work, the array must be sized with a compile-time constant, so, int a[10]; works, but int a[n]; does not.
you can do this:-
#include <algorithm>
int main(){
int arr[2000];
int n = sizeof(arr)/sizeof(arr[0]);
std::sort(arr, arr+n);
}
if you are using array instead of vector then use
sort(a,a+n);

error: ‘result’ does not name a type

I want to find minimum value in my data set.
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <iterator>
int main(){
std::vector<double> v;
std::ifstream inputFile1("263_V01_C02_R099_THx_BL_128H.dat");
if (inputFile1) {
double value;
while ( inputFile1 >> value ) {
v.push_back(value);
}
}
auto result = std::min_element(std::begin(v), std::end(v));
}
I have seen previous responses,people point to iterator not being included.How to solve this?
auto is a C++11 specifier. You need a C++11 compiler.
With gcc you can enable the C++11 features using -std=c++11:
gcc exaple:
g++ -std=c++11 main.cpp
From cppreference.com
auto specifier (since C++11)
Specifies that the type of the variable that is being declared will be automatically deduced from its initializer.
If you don't have a C++11 compiler, then you need to define the concrete type.
Eg:
std::vector<double>::iterator result = ...
BTW: std::begin() and std::end() are also C++11 features.
As sergej already pointed out auto is a C++11 specifier/keyword.
If you don't have access to a C++11 compiler you could still use this to make your code work.
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <iterator>
int main() {
std::vector<double> v;
std::ifstream inputFile1("263_V01_C02_R099_THx_BL_128H.dat");
if (inputFile1) {
double value;
while (inputFile1 >> value) {
v.push_back(value);
}
}
double result = 0; //Or other default value
std::vector<double>::iterator minIter = std::min_element(v.begin(), v.end());
if (minIter != v.end())
{
result = (*minIter);
}
std::cout << "Result is " << result << std::endl;
}
Additional hint:
auto in your code is the same as std::vector<double>::iterator in this case. So you will have an iterator as result.
You should always check an return value iterator against .end() before using it.
EDIT:
Using v.begin() and v.end() instead of std::begin(v) and std::end(v) as pointed out by sergej and NathanOliver.

C++ Unordered Map

I have a program in which I am using an iterator to get access to a value of a map entry .
#include <iostream>
#include <cstdio>
#include <unordered_map>
#include <utility>
#include <algorithm>
using namespace std;
int main()
{
int a[]={1,2,4,7,9,3,3,55,66,88,11};
int k = 58;
unordered_map<int,int> c;
int i=0;
for(auto x: a)
{
c.insert(make_pair(x,i));
i++;
}
for(auto x: c)
{
if(c.count(k-x.first)==1) printf("%d %d\n",x.second,(c.find(k-x))->second);
}
}
In the line:
if(c.count(k-x.first)==1) printf("%d %d\n",x.second,(c.find(k-x))->second);
I am getting errors especially in c.find()->second. I think it is the way to access elements from the iterator. What is wrong?
You cannot say
c.find(k-x)
Because k is an int and x is a std::pair<int, int>. Do you mean one of these two?
c.find(k - x.first)
Or
c.find(k - x.second)
As a side note, it is generally unsafe to directly derefernce the returned iterator from find because if find returns .end() (as in, it didn't find an element with that key) then you've got a problem.

why this std::bind fails?

What is the fault of this bind operation with visual studio 2013 for error C3867 ?
#include <map>
#include <vector>
#include <algorithm>
#include <functional>
int main()
{
std::map<int, int> m1, m2;
std::vector<std::map<int, int> *> pM;
std::for_each(pM.begin(), pM.end(),
std::bind(std::map<int, int>::erase , 1));
}
If you want to delete each map's element (which key is 1) in the vector. Here is a sample.
#include <map>
#include <vector>
#include <algorithm>
#include <functional>
#include <iostream>
using namespace std;
using namespace std::placeholders;
int main()
{
std::map<int, int> m1 {{1,2},{2,3},{3,4}}, m2 {{2,3},{1,5},{8,9}};
std::vector<std::map<int, int> *> pM {&m1,&m2};
size_t(std::map<int,int>::*pf)(const int& key)=&std::map<int,int>::erase;//note this line.
std::for_each(pM.begin(), pM.end(),std::bind(pf,_1,1));//note this line
for(auto& ele:m1)
{
cout<<ele.first<<","<<ele.second<<endl;
}
for(auto& ele:m2)
{
cout<<ele.first<<","<<ele.second<<endl;
}
}
As chris says:
For one thing, member functions do not decay into member function
pointers. For another, std::map::erase is overloaded.
We must use & to get member function pointer,and must tell compiler which overload function you want to choice.
So write code like this:
size_t(std::map<int,int>::*pf)(const int& key)=&std::map<int,int>::erase;
And further:
std::bind(pf,_1,1)
member function need object as its implicit first parameter, _1 do this work.The last parameter 1 is int as the key pass to map erase member function.