a generic function example using output iterator not working - c++

I have the following template function:
template<class In, class Out>
Out copy(In begin, In end, Out dest)
{
while(begin != end)
*dest++ = *begin++;
return dest;
}
and when I call the following:
static const double arr[] = {50,23, 56,1,78,23,25,26,143,120};
vector<double> values(arr, arr + sizeof(arr) / sizeof(arr[0]) );
// Using copy
// ----------
vector<double> values_copy;
copy(values.begin(), values.end(), back_inserter(values_copy));
for(int i=0 ; i < values_copy.size(); i++)
cout << values_copy[i] << endl;
I get the following compile error (btw to the g++ developers, thank you):
2-iterator.cpp: In function ‘int main()’:
2-iterator.cpp:77:63: error: call of overloaded ‘copy(std::vector<double>::iterator, std::vector<double>::iterator, std::back_insert_iterator<std::vector<double> >)’ is ambiguous
2-iterator.cpp:77:63: note: candidates are:
2-iterator.cpp:41:5: note: Out copy(In, In, Out) [with In = __gnu_cxx::__normal_iterator<double*, std::vector<double> >, Out = std::back_insert_iterator<std::vector<double> >]
/usr/include/c++/4.6/bits/stl_algobase.h:444:5: note: _OI std::copy(_II, _II, _OI) [with _II = __gnu_cxx::__normal_iterator<double*, std::vector<double> >, _OI = std::back_insert_iterator<std::vector<double> >]
[Finished in 0.7s with exit code 1]

Remove:
using namespace std;
and use std::cout, std::endl, etc. There is already std::copy function.

Related

Getting build error when trying to implement a comparator for sorting map data type?

I am trying to build a comparator for a map to be used with sort() function.
consider a map object called right with an id and coordinates as the basic member. I am trying to sort the elements of this object with euclidean distance. below is the code.
#include <iostream>
#include <vector>
#include <map>
#include <cmath>
#include <algorithm>
namespace NONBCG_DATA_ALGO
{
template<typename T>
T distance(std::vector<T> P1, std::vector<T> P2 , int dim)
{
if ((typeid(T) == typeid(int)) || (typeid(T) == typeid(double)) || (typeid(T) == typeid(float)) )
{
float accum = 0;
for(int i=0; i<dim; i++)
{
accum += pow((P2[i]-P1[i]),2);
}
return sqrt(accum);
}
else
{
throw std::invalid_argument("Type should be either int,double or float");
}
}
template<typename T>
class distance_compare_asc_comp_id_2D
{
public:
distance_compare_asc_comp_id_2D(std::vector<T> ipt):Pt(ipt){};
bool operator()(const std::pair<int,std::vector<T>>& p1,const std::pair<int,std::vector<T>>&p2)
{
if ((typeid(T) == typeid(int)) || (typeid(T) == typeid(double)) || (typeid(T) == typeid(float)) )
{
return NONBCG_DATA_ALGO::distance<T>(Pt,p1.second,2) < NONBCG_DATA_ALGO::distance(Pt,p2.second,2);
}
else
{
throw std::invalid_argument("Type should be either int,double or float");
}
}
private:
std::vector<T> Pt;
};
};
int main() {
// Write C++ code here
std::map<int,std::vector<double>> right;
right.insert(std::pair<int,std::vector<double>>(1,{2,8,3}));
right.insert(std::pair<int,std::vector<double>>(6,{2.5,5.4,3}));
sort(right.begin(),right.end(),NONBCG_DATA_ALGO::distance_compare_asc_comp_id_2D<double>(std::vector<double>{0.0,0.0}));
return 0;
}
I get the following error while building
In file included from /usr/include/c++/9/algorithm:62,
from /tmp/wxeRdlKRUn.cpp:6:
/usr/include/c++/9/bits/stl_algo.h: In instantiation of 'void std::__sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = std::_Rb_tree_iterator<std::pair<const int, std::vector<double> > >; _Compare = __gnu_cxx::__ops::_Iter_comp_iter<NONBCG_DATA_ALGO::distance_compare_asc_comp_id_2D<double> >]':
/usr/include/c++/9/bits/stl_algo.h:4899:18: required from 'void std::sort(_RAIter, _RAIter, _Compare) [with _RAIter = std::_Rb_tree_iterator<std::pair<const int, std::vector<double> > >; _Compare = NONBCG_DATA_ALGO::distance_compare_asc_comp_id_2D<double>]'
/tmp/wxeRdlKRUn.cpp:70:122: required from here
/usr/include/c++/9/bits/stl_algo.h:1968:22: error: no match for 'operator-' (operand types are 'std::_Rb_tree_iterator<std::pair<const int, std::vector<double> > >' and 'std::_Rb_tree_iterator<std::pair<const int, std::vector<double> > >')
1968 | std::__lg(__last - __first) * 2,
| ~~~~~~~^~~~~~~~~
I really appreciate any help you can provide.
molbdnilo's suggestion of using a vector of pairs fits perfectly for my usage. Thanks, everyone for the help!

error: assignment of read-only location ‘* __result’

On compilation of the given code, I get the following error messages:
/usr/include/c++/9.2.0/bits/stl_algo.h: In instantiation of ‘_OutputIterator
std::__merge(_InputIterator1, _InputIterator1, _InputIterator2, _InputIterator2, _OutputIterator,
_Compare) [with _InputIterator1 = __gnu_cxx::__normal_iterator<std::pair<int, int>*,
std::vector<std::pair<int, int> > >; _InputIterator2 = __gnu_cxx::__normal_iterator<std::pair<int,
int>*, std::vector<std::pair<int, int> > >; _OutputIterator = bool (*)(std::pair<int, int>,
std::pair<int, int>); _Compare = __gnu_cxx::__ops::_Iter_less_iter]’:
/usr/include/c++/9.2.0/bits/stl_algo.h:4929:37: required from ‘_OIter std::merge(_IIter1, _IIter1,
_IIter2, _IIter2, _OIter) [with _IIter1 = __gnu_cxx::__normal_iterator<std::pair<int, int>*,
std::vector<std::pair<int, int> > >; _IIter2 = __gnu_cxx::__normal_iterator<std::pair<int, int>*,
std::vector<std::pair<int, int> > >; _OIter = bool (*)(std::pair<int, int>, std::pair<int, int>)]’
jdoodle.cpp:61:81: required from here
/usr/include/c++/9.2.0/bits/stl_algo.h:4874:18: error: assignment of read-only location ‘* __result’
4874 | *__result = *__first2;
| ~~~~~~~~~~^~~~~~~~~~~
/usr/include/c++/9.2.0/bits/stl_algo.h:4879:18: error: assignment of read-only location ‘* __result’
4879 | *__result = *__first1;
| ~~~~~~~~~~^~~~~~~~~~~
Following is the code:
#include <iostream>
#include <cmath>
#include <vector>
#include <algorithm>
#include <utility>
#include <cfloat>
using namespace std;
struct Node
{
int left;
int right;
double dist;
};
bool x_sort(pair<int,int> x,pair<int,int> y)
{
if(x.first<y.first)
return true;
return false;
}
bool y_sort(pair<int,int> x,pair<int,int> y)
{
if(x.second<y.second)
return true;
return false;
}
Node closest_dist(vector<pair<int,int>> arr,int low,int high)
{
Node x;
double min_dist=DBL_MAX;
if(high-low+1<=3)
{
for(int i=low;i<=high;i++)
{
for(int j=i+1;j<=high;j++)
{
double dist=sqrt(pow((arr[i].first-arr[j].first),2)+pow((arr[i].second-arr[j].second),2));
if(dist<min_dist)
{
min_dist=dist;
x.left=i;
x.right=j;
x.dist=min_dist;
}
}
}
}
int mid=low+(high-low)/2;
Node x1=closest_dist(arr,low,mid);
Node x2=closest_dist(arr,mid+1,high);
double min_dist_now=min(x1.dist,x2.dist);
merge(arr.begin()+low,arr.begin()+mid,arr.begin()+mid+1,arr.begin()+high,y_sort); //line which gives the error(most probably)
vector<pair<int,int>> strip;
for(int i=low;i<=high;i++)
if((abs(arr[mid].first-arr[i].first)<min_dist_now))
strip.push_back(arr[i]);
for(int i=0;i<strip.size()-7;i++)
{
for(int j=i+1;j<=i+7&&j<strip.size();j++)
{
double dist=sqrt(pow((arr[i].first-arr[j].first),2)+pow((arr[i].second-arr[j].second),2));
if(dist<min_dist_now)
{
min_dist_now=min_dist;
x.left=i;
x.right=j;
x.dist=min_dist;
}
}
}
return x;
}
int main()
{
int n;
cin>>n;
vector<pair<int,int>> arr;
for(int i=0;i<n;i++)
{
int x,y;
cin>>x>>y;
arr.push_back(make_pair(x,y));
}
sort(arr.begin(),arr.end(),x_sort);
for(int i=0;i<n;i++)
{
cout<<arr[i].first<<" "<<arr[i].second;
cout<<"\n";
}
Node ans=closest_dist(arr,0,n-1);
cout<<ans.left<<" "<<ans.right<<" "<<ans.dist<<"\n";
return 0;
}
I have written the code as a solution to the problem https://www.spoj.com/problems/CLOPPAIR/
I am new to STL and on finding a solution to the same error, most implementations have misused the keyword 'const' that has lead to this error. However, in my case there is no usage of 'const'. Can someone please help me out on this?
Seems you mistook what the fifth parameter for std::merge is for.
That parameter should be an iterator which tells the compiler where to place the merged data. You've supplied a function however.
It looks like you are trying to supply a custom sort criteria, but that would be the sixth parameter to std::merge.
https://en.cppreference.com/w/cpp/algorithm/merge

Can not compile merge sort tree structure?

I was trying to implement merge sort tree structure but whenever i
try to merge child vector to parent vector i get compilation error . I
am stuck here .
class merge_sort_tree {
vector<int>input;
vector<vector<int> >tr;
int n;
public:
merge_tree(vector<int >p) {
n = p.size();
input = p;
tr.resize(5 * n);
}
void build(int root, int l, int r) {
if (l == r)
{
tr[root] = {input[l]};
}
int m = l + (r - l) / 2;
build(2 * root, l, m);
build(2 * root + 1, m + 1, r);
//temporary vector for merging child vectors
vector<int>tmp(tr[2 * root].size() + tr[2 * root + 1].size());
// merging child vector and storing result in tmp
merge(tr[2 * root].begin(), tr[2 * root].end(),
tr[2 * root + 1].begin(), tr[2 * root + 1].end(),
tmp.begin(), tmp.end() );
tr[root]=tmp;
}
};
In file included from c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\stl_algobase.h:71:0,
from c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\char_traits.h:39,
from c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\ios:40,
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\mingw32\bits\stdc++.h:52,
from C:\Users\Ayuu\Desktop\codes\test3.cc:1:
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\predefined_ops.h: In instantiation of 'constexpr bool __gnu_cxx::__ops::_Iter_comp_iter<_Compare>::operator()(_Iterator1, _Iterator2) [with _Iterator1 = __gnu_cxx::__normal_iterator >; _Iterator2 = __gnu_cxx::__normal_iterator >; _Compare = __gnu_cxx::__normal_iterator >]':
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\stl_algo.h:4751:14: required from '_OutputIterator std::__merge(_InputIterator1, _InputIterator1, _InputIterator2, _InputIterator2, _OutputIterator, _Compare) [with _InputIterator1 = __gnu_cxx::__normal_iterator >; _InputIterator2 = __gnu_cxx::__normal_iterator >; _OutputIterator = __gnu_cxx::__normal_iterator >; _Compare = __gnu_cxx::__ops::_Iter_comp_iter<__gnu_cxx::__normal_iterator > >]'
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\stl_algo.h:4858:37: required from '_OIter std::merge(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Compare) [with _IIter1 = __gnu_cxx::__normal_iterator >; _IIter2 = __gnu_cxx::__normal_iterator >; _OIter = __gnu_cxx::__normal_iterator >; _Compare = __gnu_cxx::__normal_iterator >]'
C:\Users\Ayuu\Desktop\codes\test3.cc:43:38: required from here
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\predefined_ops.h:123:18: error: no match for call to '(__gnu_cxx::__normal_iterator >) (int&, int&)'
{ return bool(_M_comp(*__it1, *__it2)); }
Look at this line, it expected one iterator, you gave 2
error: no match for call to '(__gnu_cxx::__normal_iterator >) (int&, int&)' { return bool(_M_comp(*__it1, *__it2)); }
Remove tmp.end() from your merge function. It requires 5 arguments not 6.
merge(tr[2 * root].begin(), tr[2 * root].end(),
tr[2 * root + 1].begin(), tr[2 * root + 1].end(),
tmp.begin());
This should work.

Store strings in a vector and sort them

I want to make a class that stores strings from the console in a vector and then sorts them alphabetically using selection sort.
This is my code so far.
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
class Dictionary
{
public:
Dictionary();
void read(vector<int>&words);
void SelectionSort(vector <int> &num);
private:
//vector<string> line_vector;
string word;
//vector<string> words;
};
Dictionary:: Dictionary()
{
//line_vector = "<empty>";
string word = "<empty>";
}
void Dictionary:: read(vector<int>& words)
{
//vector<string> words;
string word;
while( cin >> word ) words.push_back(word);
}
////////////////////////////////////////////////////////////////////////////////////
void Dictionary:: SelectionSort(vector <int> &num)
{
int i, j, first, temp;
int numLength = num.size( );
for (i= numLength - 1; i > 0; i--)
{
first = 0; // initialize to subscript of first element
for (j=1; j<=i; j++) // locate smallest between positions 1 and i.
{
if (num[j] < num[first])
first = j;
}
temp = num[first]; // Swap smallest found with element in position i.
num[first] = num[i];
num[i] = temp;
}
return;
}
void print(vector<Dictionary>& a)
{
for (int i = 0; i < a.size(); i++)
cout << a[i];
cout << "\n";
}
/////////////////////////////////////////////////////////////////////////////////////////////////////
int main()
{
Dictionary dict;
vector<Dictionary> str;
dict.read(str);
dict.SelectionSort(str);
dict.print(str);
return 0;
}
and these are the errors:
In member function 'void Dictionary::read(std::vector<int>&)':
31:46: error: no matching function for call to 'std::vector<int>::push_back(std::string&)'
31:46: note: candidates are:
In file included from /usr/include/c++/4.9/vector:64:0,
from 3:
/usr/include/c++/4.9/bits/stl_vector.h:913:7: note: void std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp = int; _Alloc = std::allocator<int>; std::vector<_Tp, _Alloc>::value_type = int]
push_back(const value_type& __x)
^
/usr/include/c++/4.9/bits/stl_vector.h:913:7: note: no known conversion for argument 1 from 'std::string {aka std::basic_string<char>}' to 'const value_type& {aka const int&}'
/usr/include/c++/4.9/bits/stl_vector.h:931:7: note: void std::vector<_Tp, _Alloc>::push_back(std::vector<_Tp, _Alloc>::value_type&&) [with _Tp = int; _Alloc = std::allocator<int>; std::vector<_Tp, _Alloc>::value_type = int]
push_back(value_type&& __x)
^
One of the error lines seems very helpful:
/usr/include/c++/4.9/bits/stl_vector.h:913:7: note:
no known conversion for argument 1
from
'std::string {aka std::basic_string<char>}'
to
'const value_type& {aka const int&}'
If you pass an argument that doesn't match the expected type for a function, then C++ will try to find any conversion from the passed type into the expected type. The conversion include 1-argument constructors and cast operators. See http://www.cplusplus.com/doc/tutorial/typecasting/
This particular error is indicating that the passed argument cannot be converted to an int.

Sorting an array of int[2] does not compile

I have a data array with 2*N ints, representing pairs, that is for even i=0,2,4,...,2*N (pairs[i], pairs[i+1]) is such a pair. The data is formatted like this because I use Matlab's mex library. I do:
int N=5;
int data[10] = {1,2,3,4,5,6,7,8,9,10};
struct Pair { int first; int second; };
Pair * pairs = (Pair *)data;
but the problem would be that there is no way to guarantee that Pair aligns as two sizeof(ints) in order first, second. See: Is the member field order of a class "stable"?
I don't want to process and copy all data into a new array, since it should not be necessary, and I need (as far as I can see) to use
typedef int Pair[2];
to be sure that it aligns correctly (no trailing garbage bytes, etc). if I then want to sort the pairs according to the first element, I could do:
#include <iostream>
#include <algorithm>
typedef int Pair[2];
int compare(Pair n1, Pair n2) { return n1[0] < n2[0]; }
int main() {
int N=5;
int data[10] = {1,2, 7,8, 13,14, 4,5, 10,11};
Pair *pairs = (Pair *)((void *)data);
std::cout << "unsorted" << std::endl;
for(int i=0; i<N;++i) std::cout << i << ": (" << pairs[i][0] << ", " << pairs[i][1] << ")" << std::endl;
std::sort(data, data+N, compare);
std::cout << "sorted" << std::endl;
for(int i=0; i<N;++i) std::cout << i << ": (" << pairs[i][0] << ", " << pairs[i][1] << ")" << std::endl;
return 0;
}
see: http://ideone.com/VyBUvc
I could summarize the error message as error: array must be initialized with a brace-enclosed initializer, see below for the complete message. It is caused by the std::sort call.
I wrapped the Pair typedef in a union here ( http://ideone.com/TVmEeZ ), and that seems to work. Why does c++ (or std::sort) not see int[2] in a similar way as a union?
Complete compiler output:
In file included from /usr/include/c++/4.8/bits/stl_pair.h:59:0,
from /usr/include/c++/4.8/bits/stl_algobase.h:64,
from /usr/include/c++/4.8/bits/char_traits.h:39,
from /usr/include/c++/4.8/ios:40,
from /usr/include/c++/4.8/ostream:38,
from /usr/include/c++/4.8/iostream:39,
from prog.cpp:1:
/usr/include/c++/4.8/bits/stl_algo.h: In instantiation of ‘void std::__insertion_sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = int (*)[2]; _Compare = bool (*)(int*, int*)]’:
/usr/include/c++/4.8/bits/stl_algo.h:2250:70: required from ‘void std::__final_insertion_sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = int (*)[2]; _Compare = bool (*)(int*, int*)]’
/usr/include/c++/4.8/bits/stl_algo.h:5514:55: required from ‘void std::sort(_RAIter, _RAIter, _Compare) [with _RAIter = int (*)[2]; _Compare = bool (*)(int*, int*)]’
prog.cpp:16:35: required from here
/usr/include/c++/4.8/bits/stl_algo.h:2186:11: error: array must be initialized with a brace-enclosed initializer
__val = _GLIBCXX_MOVE(*__i);
^
In file included from /usr/include/c++/4.8/algorithm:62:0,
from prog.cpp:2:
/usr/include/c++/4.8/bits/stl_algo.h:2188:17: error: invalid array assignment
*__first = _GLIBCXX_MOVE(__val);
^
/usr/include/c++/4.8/bits/stl_algo.h: In instantiation of ‘_RandomAccessIterator std::__unguarded_partition(_RandomAccessIterator, _RandomAccessIterator, const _Tp&, _Compare) [with _RandomAccessIterator = int (*)[2]; _Tp = int [2]; _Compare = bool (*)(int*, int*)]’:
/usr/include/c++/4.8/bits/stl_algo.h:2319:78: required from ‘_RandomAccessIterator std::__unguarded_partition_pivot(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = int (*)[2]; _Compare = bool (*)(int*, int*)]’
/usr/include/c++/4.8/bits/stl_algo.h:2360:62: required from ‘void std::__introsort_loop(_RandomAccessIterator, _RandomAccessIterator, _Size, _Compare) [with _RandomAccessIterator = int (*)[2]; _Size = int; _Compare = bool (*)(int*, int*)]’
/usr/include/c++/4.8/bits/stl_algo.h:5513:44: required from ‘void std::sort(_RAIter, _RAIter, _Compare) [with _RAIter = int (*)[2]; _Compare = bool (*)(int*, int*)]’
prog.cpp:16:35: required from here
/usr/include/c++/4.8/bits/stl_algo.h:2287:35: error: invalid conversion from ‘const int*’ to ‘int*’ [-fpermissive]
while (__comp(*__first, __pivot))
^
/usr/include/c++/4.8/bits/stl_algo.h:2290:34: error: invalid conversion from ‘const int*’ to ‘int*’ [-fpermissive]
while (__comp(__pivot, *__last))
^
In file included from /usr/include/c++/4.8/bits/stl_pair.h:59:0,
from /usr/include/c++/4.8/bits/stl_algobase.h:64,
from /usr/include/c++/4.8/bits/char_traits.h:39,
from /usr/include/c++/4.8/ios:40,
from /usr/include/c++/4.8/ostream:38,
from /usr/include/c++/4.8/iostream:39,
from prog.cpp:1:
/usr/include/c++/4.8/bits/stl_heap.h: In instantiation of ‘void std::make_heap(_RAIter, _RAIter, _Compare) [with _RAIter = int (*)[2]; _Compare = bool (*)(int*, int*)]’:
/usr/include/c++/4.8/bits/stl_algo.h:1970:47: required from ‘void std::__heap_select(_RandomAccessIterator, _RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = int (*)[2]; _Compare = bool (*)(int*, int*)]’
/usr/include/c++/4.8/bits/stl_algo.h:5363:59: required from ‘void std::partial_sort(_RAIter, _RAIter, _RAIter, _Compare) [with _RAIter = int (*)[2]; _Compare = bool (*)(int*, int*)]’
/usr/include/c++/4.8/bits/stl_algo.h:2355:68: required from ‘void std::__introsort_loop(_RandomAccessIterator, _RandomAccessIterator, _Size, _Compare) [with _RandomAccessIterator = int (*)[2]; _Size = int; _Compare = bool (*)(int*, int*)]’
/usr/include/c++/4.8/bits/stl_algo.h:5513:44: required from ‘void std::sort(_RAIter, _RAIter, _Compare) [with _RAIter = int (*)[2]; _Compare = bool (*)(int*, int*)]’
prog.cpp:16:35: required from here
/usr/include/c++/4.8/bits/stl_heap.h:446:25: error: array must be initialized with a brace-enclosed initializer
_ValueType __value = _GLIBCXX_MOVE(*(__first + __parent));
^
/usr/include/c++/4.8/bits/stl_heap.h: In instantiation of ‘void std::__pop_heap(_RandomAccessIterator, _RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = int (*)[2]; _Compare = bool (*)(int*, int*)]’:
/usr/include/c++/4.8/bits/stl_algo.h:1973:50: required from ‘void std::__heap_select(_RandomAccessIterator, _RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = int (*)[2]; _Compare = bool (*)(int*, int*)]’
/usr/include/c++/4.8/bits/stl_algo.h:5363:59: required from ‘void std::partial_sort(_RAIter, _RAIter, _RAIter, _Compare) [with _RAIter = int (*)[2]; _Compare = bool (*)(int*, int*)]’
/usr/include/c++/4.8/bits/stl_algo.h:2355:68: required from ‘void std::__introsort_loop(_RandomAccessIterator, _RandomAccessIterator, _Size, _Compare) [with _RandomAccessIterator = int (*)[2]; _Size = int; _Compare = bool (*)(int*, int*)]’
/usr/include/c++/4.8/bits/stl_algo.h:5513:44: required from ‘void std::sort(_RAIter, _RAIter, _Compare) [with _RAIter = int (*)[2]; _Compare = bool (*)(int*, int*)]’
prog.cpp:16:35: required from here
/usr/include/c++/4.8/bits/stl_heap.h:339:28: error: array must be initialized with a brace-enclosed initializer
_ValueType __value = _GLIBCXX_MOVE(*__result);
^
In file included from /usr/include/c++/4.8/bits/stl_algo.h:61:0,
from /usr/include/c++/4.8/algorithm:62,
from prog.cpp:2:
/usr/include/c++/4.8/bits/stl_heap.h:340:17: error: invalid array assignment
*__result = _GLIBCXX_MOVE(*__first);
^
std::sort(data, data+N, compare);
You are sorting data, not pairs. That said, your new approach is still undefined behaviour, and thus not guaranteed to work1. You are essentially trying to fit a square peg into a round hole. If you want to use std::sort, present valid data – which means copying in your case, or writing a custom iterator which treats an array as a collection of consecutive pairs.
1 That’s a humungous understatement. – Do not do this.
Exchanging your array of two int for a std::pair<int,int> did the trick for me (live at ideone):
#include <iostream>
#include <algorithm>
#include <memory>
typedef std::pair<int,int> Pair;
bool compare(const Pair& i, const Pair& j) { return i.first < j.first; }
int main() {
const int N=5;
Pair pairs[N] = {{1,2}, {7,8}, {13,14}, {4,5}, {10,11}};
std::cout << "unsorted" << std::endl;
for(int i=0; i<N;++i) std::cout << i << ": (" << pairs[i].first << ", " << pairs[i].second << ")" << std::endl;
std::sort(pairs, pairs+N, compare);
std::cout << "sorted" << std::endl;
for(int i=0; i<N;++i) std::cout << i << ": (" << pairs[i].first << ", " << pairs[i].second << ")" << std::endl;
}
An alternative would be encapsulating the array of two int inside a struct. The problem in your code is that std::sort need an array of comparable (you fixed it with your compare function) and copy-or-move-assignable items (arrays are neither)
Maybe even better (less changes to your code) would be using std::array:
#include <iostream>
#include <algorithm>
#include <memory>
typedef std::array<int, 2> Pair;
bool compare(const Pair& i, const Pair& j) { return i[0] < j[0]; }
int main() {
const int N=5;
Pair pairs[N] = {1,2, 7,8, 13,14, 4,5, 10,11};
std::cout << "unsorted" << std::endl;
for(int i=0; i<N;++i) std::cout << i << ": (" << pairs[i][0] << ", " << pairs[i][1] << ")" << std::endl;
std::sort(pairs, pairs+N, compare);
std::cout << "sorted" << std::endl;
for(int i=0; i<N;++i) std::cout << i << ": (" << pairs[i][0] << ", " << pairs[i][1] << ")" << std::endl;
}