Not sure if I have a simple typo somewhere, but I'm running into issues in sorting a deque of tuples.
So, my deque looks like this:
std::deque<boost::tuple<unsigned int, unsigned int> > messages;
And then I have my call to sort:
sort(messages.begin(), messages.end(), msg_sort_criteria);
And my sorting function:
bool msg_sort_criteria(boost::tuple<unsigned int, unsigned int> lhs, boost::tuple<unsigned int, unsigned int> rhs)
{
return boost::get<1>(lhs) < boost::get<1>(rhs);
}
What happens is that I get errors in stl_heap.h and stl_algo.h.
For instance,
Called object type '<bound member function type>' is not a function or
function parameter.
Edit:
For clarification, this is all taking place within private members of a class.
class Messages::MessageImpl{
private:
std::deque<boost::tuple<unsigned int, unsigned int> > messages;
bool msg_sort_criteria(boost::tuple<unsigned int, unsigned int> lhs, boost::tuple<unsigned int, unsigned int> rhs)
{
return boost::get<1>(lhs) < boost::get<1>(rhs);
}
void fn()
{
sort(msg_queue_.begin(), msg_queue_.end(), msg_sort_criteria);
}
}
Mostly reposting from comment.
Change your implementation to:
class Messages::MessageImpl{
private:
std::deque<boost::tuple<unsigned int, unsigned int> > messages;
static bool msg_sort_criteria(boost::tuple<unsigned int, unsigned int> lhs,
boost::tuple<unsigned int, unsigned int> rhs)
{
return boost::get<1>(lhs) < boost::get<1>(rhs);
}
void fn()
{
sort(msg_queue_.begin(), msg_queue_.end(), &MessageImpl::msg_sort_criteria);
}
};
Related
I am getting below error:
:60:8: error: request for member 'push' in 'pq', which is of
non-class type 'std::priority_queue,
std::vector >, std::function, std::pair)> >(comparator)' 60 | pq.push(p1);
My code is as below:
Declared a comparator for priority_queue as below:
class comparator
{
bool operator ()(std::pair<int, int> &p, std::pair<int, int> &q)
{
return (p.second < q.second);
}
};
Declared priority queue as below:
std::priority_queue<std::pair<int, int>, vector<std::pair<int, int>>, std::function<bool(pair<int, int>, pair<int, int>)>> pq(comparator);
make pair as below:
auto p1 = make_pair(1, 3);
pushed it to priority_queue as:
pq.push(p1);
Can anyone please tell, what i am doing wrong here
The operator() must be public and should also be const qualified.
You don't need std::function here. Just supply the comparator as the third template parameter directly.
#include <queue>
#include <utility>
#include <vector>
struct comparator {
// must be public and should be const qualified:
bool operator()(std::pair<int, int> &p, std::pair<int, int> &q) const {
return p.second < q.second;
}
};
int main() {
std::priority_queue<std::pair<int, int>, std::vector<std::pair<int, int>>,
comparator> // <- the proper comparator
pq;
auto p1 = std::make_pair(1, 3);
pq.push(p1);
}
priority_queue<pair<int, int>, vector<pair<int, int>>, comparator> pq;
static bool comparator(pair<int, int> &m, pair<int, int> &n) {
if (m.second < n.second) return true;
else return false;
}
Error:
I defined my comparator inside a class, and try to declare the priority queue inside another function in the same class, and the error happens.
The third template parameter to std::priority_queue is a type.
comparator is not a type. It is a function.
But before you can fix this, there are two more problems to fix:
types and object must be declared before they are used, and the shown code does not declare comparator before using it.
comparators must taken their parameters as const references, they are not allowed to modify them.
Therefore, your comparator should be:
static bool comparator(const pair<int, int> &m, const pair<int, int> &n)
Its type is: bool (*)(const pair<int, int> &, const pair<int, int> &)
That's what the third parameter to std::priority_queue template should be, and then the actual comparator must be passed to the object's constructor, std::priority_queue has an overloaded constructor that takes an instance of the comparator as a parameter:
static bool comparator(const pair<int, int> &m, const pair<int, int> &n) {
if (m.second < n.second) return true;
else return false;
}
priority_queue<pair<int, int>, vector<pair<int, int>>,
bool (*)(const pair<int, int> &, const pair<int, int> &)
> pq{comparator};
However, you will discover that most of this is unnecessary, and I showed it only for pedanticty's purposes. std::priority_queue's default comparator template parameter will work just fine, because std::pair implements operator<:
priority_queue<pair<int, int>, vector<pair<int, int>>> pq{comparator};
The third template argument for template type parameter must be a type, whereas comparator is a function. You may get the type of the function with decltype(&comparator).
std::priority_queue<std::pair<int, int>, std::vector<std::pair<int, int>>, decltype(&comparator)> pq(comparator);
The last cppreference example with lambda is very similar to your code https://coliru.stacked-crooked.com/view?id=86f63b09847ba22e.
I have difficulty understanding this part of a code? Is it possible to get pictorial/diagram explanation.
//test.h
typedef std::map<std::string, std::string> mType;
static const m_Type::value_type data[] = {
m_Type::value_type("A", "B"),
m_Type::value_type("C", "D"),
m_Type::value_type("E", "F")
};
//test.cc
void test(std::map<std::string, std::string>::value_type data)
{
cout<<data[0].first<<endl;
}
//main.cc
test(data);
In main.cc I wanted to call test() to print elements but getting error
main.cc: In function 'void test(std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >)':
main.cc:10: error: no match for 'operator[]' in 'data[0]'
You have to declare the function the following way
void test( const std::map<std::string, std::string>::value_type data[] )
{
cout<<data[0].first<<endl;
}
because originally data is defined as an array that you are going to pass to the function. Otherwise you may not use the subscript operator.
Also you need to use qualifier const for the parameter because array data also is defined as a constant array.
As for this type
m_Type::value_type
then it is equivalent to std::pair<const std::string, std::string> So this declaration
static const m_Type::value_type data[] = { /*...*/ };
is equivalent to
static const std::pair<const std::string, std::string> data[] = { /*...*/ };
You are supposed to pass to test a value_type not the whole map.
A value_type corresponds to a pair(key, value) and is define like so in stdlib : typedef pair<const Key, Type> value_type;
therefore this data[0]makes no sense. Should be data.first
I defined a list of pairs and wish to access them using an iterator, following an example.
class A{
private:
list<pair<size_type,size_type> > l_edge_;
public:
void function() const{
list<pair<size_type,size_type> >::iterator Iter_;
Iter_ = l_edge_.begin();
}
}
However, I got a compilation error. How can I fix it?
error: no match for 'operator=' (operand types are 'const iterator
{aka const std::_List_iterator<std::pair<unsigned int, unsigned int> >}' and
'std::list<std::pair<unsigned int, unsigned int> >::const_iterator
{aka std::_List_const_iterator<std::pair<unsigned int, unsigned int> >}')
My guess is that you are trying to write a const member function, and not what you copied in the question:
void function() const
{
Iter_ = l_edge_.begin();
}
Now, since the function is const, the l_edge_ member is also const, and so, begin() returns a const_iterator instead of a plain iterator. But that hardly matters because the Iter_ member is also const, so it cannot be assigned to.
Usually you do not want to declare iterators as member variables, unless very special needs. Instead, just declare a local one when you need it, and of the appropriate constness:
class A
{
private:
list<pair<size_type,size_type> > l_edge_;
public:
//const member function
void function() const
{
list< pair<size_type,size_type> >::const_iterator iter = l_edge_.begin();
}
//non-const member function
void function()
{
list< pair<size_type,size_type> >::iterator iter = l_edge_.begin();
}
};
I've got an error while using find() function. Here is the code:
#include <iostream>
#include <map>
#define N 100000
using namespace std;
int main (int argc, char * const argv[]) {
map<int,int> m;
for (int i=0; i<N; i++) m[i]=i;
find(m.begin(), m.end(), 5);
return 0;
}
I'm getting an compiller error:
error: no match for 'operator==' in '__first. __gnu_debug::_Safe_iterator<_Iterator, _Sequence>::operator* [with _Iterator = std::_Rb_tree_iterator<std::pair<const int, int> >, _Sequence = __gnu_debug_def::map<int, int, std::less<int>, std::allocator<std::pair<const int, int> > >]() == __val'
Including 'algorithm' nothing changes. Compiling in VS2008 shows similar error.
I know about m.find(), but I realy need to use find() too.
Thanks a lot for your assistance!
P.S. Actualy, the task is to compare speed of m.find(5) and find(m.begin(), m.end(), 5), so I need to make both of them work properly.
begin() and end() on all STL containers provide access to elements of those collections. Type of those elements is known as value_type of the container. For std::map<Key, Value>, its value_type is std::pair<Key, Value>. Therefore, your find function is trying to find a pair<int, int> which is equal to 5. Since there's no operator== defined to compare pair<int, int> and int, you get the error.
The correct way to do this (so long as you want to avoid member find()) is to use std::find_if:
template <class First>
struct first_equal
{
const First value;
first_equal(const First& value)
: value(value)
{
}
template <class Second>
bool operator() (const std::pair<First, Second>& pair) const
{
return pair.first == value;
}
};
...
find_if(m.begin(), m.end(), first_equal<int>(5));
You could also overload operator== for pair and int to do what you want, but it's a very hackish way (because it will affect all your code, and because such a comparison has no meaning in general).
find() requires a parameter that can be compared to *iterator. For your map, this will be pair<int,int>. You'll need to create a dummy pair, plus a comparison functor to compare the pairs.
Just use m.find(5)