C++ Templates Error: no matching function for call - c++

I get the error mentioned here:
C++ Templates Error: no matching function for call std::vector<int, std::allocator<int> >
Here is the error(again):
main.cpp: In function ‘int main()’:
main.cpp:21:21: error: no matching function for call to ‘Test<int>::foo(std::vector<int, std::allocator<int> >)’
main.cpp:21:21: note: candidate is:
main.cpp:14:6: note: void Test<T>::foo(std::vector<T>&) [with T = int]
main.cpp:14:6: note: no known conversion for argument 1 from ‘std::vector<int, std::allocator<int> >’ to ‘std::vector<int, std::allocator<int> >&’
The problem is that I have a more complex situation and I don't know how to solve it (without breaking too much code).
I have a Binary Search Tree class that is generic. I want to populate a vector of elements of type T(generic) with all the values from the binary search tree nodes - so I can't make the vector const. The function that traverses the tree is recursive.
So I have:
/*main*/
BST<int> t;
t.add(21);
t.add(12);
//.... etc.
vector<int> elements;
t.inorder(elements);
/* ------------ */
and:
/*BST.h*/
template<typename T>
class BST{
//....
Node<T>* root;
//....
void inorder_rec(Node<T>* root, vector<T>& result);
void inorder(vector<T>& result);
//....
};
template<typename T>
void BST<T>::inorder_rec(Node<T>* root, vector<T>& result){
// recursive call for the child nodes
}
void BST<T>::inorder(vector<T>& result){
inorder_rec(this->root, result);
}
/* ------------ */

You are trying to call a function that takes a reference with a temporary. A temporary can only bind to a reference to const. Also, it would be wise to show, where the error actually originated.

Is this your actual code? The definitions of inorder and inorder_rec need to have return types. Otherwise, this part of the code looks fine, no temporary in sight:
vector<int> elements;
t.inorder(elements);
Dumb question, but did you save your file? Or is this error coming from a different part of the code?

Related

C++ error:[ invalid operands to binary expression ('std::map<int, std::function<void ()>, std::less<int>...]

With this following code:
#include <map>
#include <functional>
#include "main.h"
std::map<int,std::function<void()>> fnc_event_to;
void testFunction();
void initialize() {
fnc_event_to[1] = testFunction;
bool boolean = fnc_event_to[2] == testFunction;//<- error
pros::lcd::initialize();
pros::lcd::print(2,"%d",boolean);
}
I recieve this error:
invalid operands to binary expression ('std::map<int, std::function<void ()>, std::less<int>, std::allocator<std::pair<const int, std::function<void ()> > > >::mapped_type' (aka 'std::function<void ()>') and 'void (*)()')
How come I can assign the function pointer to the map but I am not able to compare it with a function pointer?
Also, if a key is not defined, what will the map return?
Is there a way to compare the std::function so I can see whether its a null function pointer or is it defined already?
Or is there a better solution for this? Originally, I'm using a while(1) loop to trap the thread and the map is just a map of what the program should do when a variable reaches the key(int). The variable is changed in a separate task so its multitasking. I couldn't use the .contains() method since I'm not using C++ 20 yet.
This is just posted for reference. Answers are quoted from #0x499602D2 and #LightnessRacesInOrbit.
Either use:
if (fnc_event_to[2]){
}
Or
if(fnc_event_to.find(2) != fnc_event_to.end()){
}
Be aware that the first option will create an empty element, so if you give the map the same value, it will already be created, and it will return true.
The standard class std::function has only these comparison operator ==
template<class R, class... ArgTypes>
bool operator==(const function<R(ArgTypes...)>&, nullptr_t) noexcept;
template<class R, class... ArgTypes>
bool operator==(nullptr_t, const function<R(ArgTypes...)>&) noexcept;
So you can only check whether an object of the class is "empty".

c++ pthread_create returning value

I am trying out multithreading of inorder traversal of binary trees. I am getting errors due to pthread_create.
#include <iostream>
#include <pthread.h>
#include <list>
using namespace std;
static pthread_t threads[9];
static int count=0;
struct node
{
int value=0;
node *left=NULL;
node *right=NULL;
};
list<int> inordertraversal(node* n)
{
list<int> l1,l2;
if(n->left!=NULL)
list<int> l1=pthread_create(&threads[count++],NULL,inordertraversal,n->left);
if(n->right!=NULL)
list<int> l2=pthread_create(&threads[count++],NULL,inordertraversal,n->right);
list<int> l;
l.insert(l.begin(),l1.begin(),l1.end());
l.push_back(n->value);
l.insert(l.end()--,l2.begin(),l2.end());
return l;
}
struct node* newNode(int data)
{
node* node;
node->value=data;
node->left=NULL;
node->right=NULL;
return node;
}
int main()
{
struct node *root=newNode(7);
root->left=newNode(9);
root->right=newNode(5);
root->left->left=newNode(13);
root->left->right=newNode(17);
root->right->left=newNode(56);
root->right->right=newNode(21);
root->left->left->left=newNode(45);
root->right->left->right=newNode(45);
root->left->left->right=newNode(67);
list<int> l=inordertraversal(root);
for(list<int>::iterator it=l.begin();it!=l.end();it++)
{
cout<<*it<<" ";
}
}
I would like to return list elements from the function passed on to the thread using pthread_create. The error is as follows:-
/usr/include/pthread.h|244|error: initializing argument 3 of ‘int pthread_create(pthread_t*, const pthread_attr_t*, void* ()(void), void*)’ [-fpermissive]|
/home/dinu94/dummyspace/interview_prep/ThreadedBinaryTree/main.cpp|25|error: conversion from ‘int’ to non-scalar type ‘std::list’ requested|
/home/dinu94/dummyspace/interview_prep/ThreadedBinaryTree/main.cpp|28|error: invalid conversion from ‘std::list ()(node)’ to ‘void* ()(void)’ [-fpermissive]|
/usr/include/pthread.h|244|error: initializing argument 3 of ‘int pthread_create(pthread_t*, const pthread_attr_t*, void* ()(void), void*)’ [-fpermissive]|
/home/dinu94/dummyspace/interview_prep/ThreadedBinaryTree/main.cpp|28|error: conversion from ‘int’ to non-scalar type ‘std::list’ requested
I am not sure how to proceed.
edit: what are the alternative ways of returning value if pthread_create is the wrong way to do?
Thanks
A pthread thread function has to conform to function definition specified by library:
int pthread_create(pthread_t*, const pthread_attr_t*, void* ()(void), void*)
so, your function list<int> inordertraversal(node* n) does not conform to void* ()(void)
you will have to change your function signature to a function which conforms to above signature and then call that recursively.
void* inorder(void)
{
pthread_create(&threads[count++],NULL,wrapper,(void *)n->left);
}
Have list<int> l; as a class member, so that you dont need to pass it around with every function call.
You're misinterpreting what pthread_create does. It just creates the thread and returns the status of the thread creation (did it work or fail). It doesn't handle at all what the function running in the thread returns. In fact the thread function probably shouldn't be returning the result at all. It should probably be updating some common variable accessible to all threads (at which point mutexes or some other mutual exclusion mechanism are going to be needed).
pthread_create needs a function pointer which should have type void* ()(void*).
Your function has return type list .

Dijkstras algorithm with priority_queue

I am trying to implement Dijkstra's algorithm. I am using this priority_queue
priority_queue<pair<PathInfo,string>,vector<pair<PathInfo,string> >,QueueComp> p;
where
class QueueComp{
PathComp* pc;
public:
QueueComp(PathComp*);
bool operator ()(const pair<PathInfo,string>&,const pair<PathInfo,string>& );
};
is my "Compare" function. The error is that QueueComp does not have a default constructor and I am not permitted to create one. What can I do to make my code compile? Btw this is the error
error: no matching function for call to 'QueueComp::QueueComp()'
This is the pathcomp.h
class PathComp{
public:
virtual bool betterThan(const PathInfo& path1,const PathInfo& path2)=0;
};
This is the pathcomppl.h
#include "pathcomp.h"
class PathCompPL:public PathComp{
public:
virtual bool betterThan(const PathInfo& path1,const PathInfo& path2);
};
This is the pathcomppl.cpp
#include "pathcomppl.h"
bool PathCompPL::betterThan(const PathInfo& path1,const PathInfo& path2){
if (path1.getTotalPrice()>path2.getTotalPrice())
return true;
if (path1.getTotalPrice()==path2.getTotalPrice() && path1.getTotalLength()>path2.getTotalLength())
return true;
return false;
}
Expanded error message
main.cpp: In constructor ‘std::priority_queue<_Tp, _Sequence, _Compare>::priority_queue(const _Compare&, const _Sequence&) [with _Tp = std::pair<PathInfo, std::basic_string<char> >; _Sequence = std::vector<std::pair<PathInfo, std::basic_string<char> > >; _Compare = QueueComp]’:
main.cpp:11:87: error: no matching function for call to ‘QueueComp::QueueComp()’
main.cpp:11:87: note: candidates are:
In file included from main.cpp:5:0:
queuecomp.h:14:5: note: QueueComp::QueueComp(PathComp*)
queuecomp.h:14:5: note: candidate expects 1 argument, 0 provided
queuecomp.h:10:7: note: QueueComp::QueueComp(const QueueComp&)
queuecomp.h:10:7: note: candidate expects 1 argument, 0 provided
You need to initialize your priority queue with additional parameter since you have non-default constructor.
priority_queue<pair<PathInfo,string>,vector<pair<PathInfo,string> >,QueueComp> p(QueueComp(ptrToPathCompObject));
The additional parameter (QueueComp(ptrToPathCompObject)) should fix your problem.
I am assuming that you have already implemented the operator() in QueueComp class.
You do not have a default constructor, because you are supposed to initialize the variable called pc. You have this constructor:
QueueComp(PathComp*);
You have to implement it so that pc is associated to the parameter.
As about your second question: The first element is your next priority, the second element is the set of lower priorities and the third is the queue comparison. I hope this helps you.
It looks like your issue is with implementing a proper comparator. One alternative you might consider is to create the comparator like the following
struct CompareEdgeWeights : public binary_function<PathInfo*, PathInfo*, bool>
{
bool operator()(const PathInfo* left, const PathInfo* right) const
{
return left->getEdgeWeight() > right->getEdgeWeight();
}
}; // end struct
// Priority queue of node edges
priority_queue<PathInfo*,vector<PathInfo*>,CompareEdgeWeights > * edgePriorityQueue;
Have this struct inherit from binary_function and overload the operator (). You can then use this as your comparator for keeping the edges sorted from lowest to highest weight value. Note: you may have to tweak this a bit to conform to your implementation. It is difficult to give a 100% correct suggestion without seeing more of your implementation.

No matching function for call

I've been getting this error, and I can't figure out how to fix it:
btree.tem:98: instantiated from 'std::pair<typename btree<T>::iterator, bool> btree<T>::insert(const T&) [with T = char]'
test.cpp:13: instantiated from here
btree.tem:37: error: no matching function for call to 'btree<char>::addElem(std::_List_iterator<node<char>*>&, node<char>*&)'
btree.h:178: note: candidates are: void btree<T>::addElem(std::_List_iterator<node<T>*>&, node<T>&) [with T = char]
btree.tem:98: instantiated from 'std::pair<typename btree<T>::iterator, bool> btree<T>::insert(const T&) [with T = char]'
test.cpp:13: instantiated from here
btree.tem:48: error: no matching function for call to 'btree<char>::addElem(std::_List_iterator<node<char>*>&, node<char>*&)'
Inside my header file I have this setter function:
void addElem (std::_List_iterator<node<T>*>& itr, node <T>& n) {
neighbours.insert(itr, n);
}
and I don't know what's wrong with it. The error seems to happen whenever I call it like this:
class list < node<T>* >::iterator itr = bt->level().begin();
node <T>*n = new node<T>(elem, bt->max());
bt->addElem(itr, n);
What is the problem?
The compiler is looking for:
btree<char>::addElem(std::_List_iterator<node<char>*>&, node<char>*&)
But it only found something for:
btree<char>::addElem(std::_List_iterator<node<char>*>&, node<char>&)
You're passing a pointer to your function. You've not defined an addElem that takes a pointer as its last argument.
The error is not "instatiated from..." - that's the context describing which template instantiations lead to the error.
The error is
btree.tem:37: error: no matching function for call to
'btree<char>::addElem(std::_List_iterator<node<char>*>&, node<char>*&)'
And a candidate is listed:
note: candidates are:
void btree<T>::addElem(std::_List_iterator<node<T>*>&, node<T>&)
[with T = char]
So it is expecting a node<char>, not a pointer node<char>*.
n is a pointer, so you have to write this:
bt->addElem(itr, *n);
It is clear from the error message:
btree.tem:37: error: no matching function for call to
'btree<char>::addElem(std::_List_iterator<node<char>*>&, node<char>*&)'
btree.h:178: note: candidates are:
void btree<T>::addElem(std::_List_iterator<node<T>*>&, node<T>&) [with T = char]
See the second parameter type in the error, as well as in the suggested candidates.

C++ stable_partition Compiler Error

I'm trying to extend an example I found in Koenig and Moo's "Accelerated C++." I've got the following code which attempts to split a vector into two partitions.
#include <algorithm>
#include <vector>
#include <iostream>
using namespace std;
struct MyClass {
int* MyInt;
MyClass() : MyInt(NULL) {}
};
struct AnalyzeMemOps {
vector<MyClass> AllMyClassRecords; // Where I keep the MyClass instances
bool sameBaseReg(MyClass m);
vector<MyClass> splitBySameBase(vector<MyClass>& main);
AnalyzeMemOps() {}
};
// Predicate function for stable_partition
bool AnalyzeMemOps::sameBaseReg(MyClass m) {
return true;
}
vector<MyClass> AnalyzeMemOps::splitBySameBase(vector<MyClass>& main) {
vector<MyClass>::iterator it =
stable_partition(main.begin(), main.end(), sameBaseReg); // Error is here
vector<MyClass> sameBases(it, main.end());
main.erase(it, main.end());
// Print results
cout << "Split By Same Base: Returning SameBase Instrs\n";
for (vector<MyClass>::iterator i = sameBases.begin(); i != sameBases.end(); ++i) {
cout << " " << i->MyInt << "\n";
}
return sameBases;
}
int main() {
AnalyzeMemOps AMCR;
MyClass m;
AMCR.AllMyClassRecords.push_back(m);
AMCR.AllMyClassRecords.push_back(m);
AMCR.AllMyClassRecords.push_back(m);
vector<MyClass> t = AMCR.splitBySameBase(AMCR.AllMyClassRecords);
}
I get an error when I attempt to compile this file with g++:
Tile.cpp: In member function \u2018std::vector<MyClass, std::allocator<MyClass> > AnalyzeMemOps::splitBySameBase(std::vector<MyClass, std::allocator<MyClass> >&)\u2019:
Tile.cpp:26: error: no matching function for call to \u2018stable_partition(__gnu_cxx::__normal_iterator<MyClass*, std::vector<MyClass, std::allocator<MyClass> > >, __gnu_cxx::__normal_iterator<MyClass*, std::vector<MyClass, std::allocator<MyClass> > >, <unresolved overloaded function type>)\u2019
/usr/include/c++/4.4/bits/stl_algo.h:1864: note: candidates are: _BIter std::stable_partition(_BIter, _BIter, _Predicate) [with _BIter = __gnu_cxx::__normal_iterator<MyClass*, std::vector<MyClass, std::allocator<MyClass> > >, _Predicate = bool (AnalyzeMemOps::*)(MyClass)]
make: *** [a.out] Error 1
Obviously this is a toy example, but I've checked the function prototypes and I'm not sure where I'm going wrong here. Any suggestions?
The problem is that sameBaseReg is a member function of AnalyzeMemOps. You can't use it like an ordinary non-member function because it can only be called on an object.
If you have a modern compiler that supports C++0x, C++ TR1, or if you have Boost handy, you can use bind to bind the pointer to member function to the this object:
std::bind(&AnalyzeMemOps::sameBaseReg, this, std::placeholders::_1)
In the current C++ standard library, the <functional> library has std::mem_fun, std::bind1st, and other functions that can help with this, but they are an absolute beating to use effectively.
You'll need to use mem_fun to turn the member function into an function object, then use bind1st to supply the this pointer.
I was never particularly successful getting this stuff to work on a regular basis (the standard library algorithms seem to be mainly designed for use with freestanding functions or hand-written predicate classes), but something like this should do the trick:
vector<MyClass>::iterator it =
stable_partition(main.begin(),
main.end(),
bind1st(mem_fun(&AnalyzeMemOps::sameBaseReg),
this));
mem_fun gives you back a function object that takes two arguments, the first being the object to invoke mem_fun's member function on, and the second being the single argument to the member function.
bind1st takes a function object that takes two arguments, and returns you a new one that takes one argument, which when invoked via operator() will call the original function object with the bind1st's argument as its first argument and the supplied argument as the second.
The end result is that a new function object is created, that takes one argument, and that will call this->sameBaseReg, passing in the supplied argument.