I was parallelizing a for loop (that iterates through a stl list) using parallel_for_each, but I got a compile time error saying that there's no matching function call.
//TBB headers
#include "tbb/parallel_for_each.h"
class FUNCTOR
{
public:
FUNCTOR(
CLASS_A& tree,
CLASS_B *groups,
const CLASS_C** default_dominator,
const CLASS_D& filter
):
tree(tree),
groups(groups),
default_dominator(default_dominator),
filter(filter)
{}
// Iterator dereferences to a pointer
void operator()(const ELEMENT_OF_LIST_A*& keeper) const
{
/*something*/
}
private:
CLASS_A& tree;
CLASS_B *groups;
const CLASS_C** default_dominator;
const CLASS_D& filter;
};
void some_function
(
CLASS_A& tree,
CLASS_B *groups,
const CLASS_C** default_dominator,
const LIST_A& keepers,
const CLASS_D& filter
)
{
// Some code that claims processors
//LIST_A_ITER begin = keepers.begin();
//LIST_A_ITER end = keepers.end();
//const ELEMENT_OF_LIST_A* keeper = *begin
tbb::parallel_for_each
(
keepers.begin(), keepers.end(),
FUNCTOR(
tree,
groups,
default_dominator,
filter
)
);
}
Error I got was:
error: no matching function for call to 'tbb::internal::parallel_do_operator_selector<tbb::internal::parallel_for_each_body<FUNCTOR, LIST_A_ITER>, ELEMENT_OF_LIST_A*>::call(const tbb::internal::parallel_for_each_body<FUNCTOR, LIST_A_ITER>&, ELEMENT_OF_LIST_A*, tbb::internal::do_iteration_task_iter<LIST_A_ITER, tbb::internal::parallel_for_each_body<FUNCTOR, LIST_A_ITER>, ELEMENT_OF_LIST_A*>::feeder_type&)'
note: candidate is: static void tbb::internal::parallel_do_operator_selector<Body, Item>::call(const Body&, A1&, A2&) [with A1 = ELEMENT_OF_LIST_A*, A2 = tbb::internal::parallel_do_feeder_impl<tbb::internal::parallel_for_each_body<FUNCTOR, LIST_A_ITER>, ELEMENT_OF_LIST_A*>, Body = tbb::internal::parallel_for_each_body<FUNCTOR, LIST_A_ITER>, Item = ELEMENT_OF_LIST_A*]
What went wrong?
Thanks!
The operator() for FUNCTOR has an extraneous extra level of indirection. Declare it without the *, e.g.:
const ELEMENT_OF_LIST_A& keeper
Related
I am trying to use a "QMap", in the class prototype:
QMap<QString, TargetsInfo*> m_targets;
In an access method I have:
TargetsInfo* TargetsModel::addTarget(int division, int camera, int map) const {
TargetsInfo* target = getTarget(division, camera, map);
if (target == nullptr) {
const QString key = makeKey(division, camera, map);
target = new TargetsInfo();
if ( target != nullptr ) {
m_targets.insert(key, target);
}
}
return target;
}
TargetsInfo* TargetsModel::getTarget(int division, int camera, int map) const {
const QString key = makeKey(division, camera, map);
QMap<QString, TargetsInfo*>::iterator itr = m_targets.find(key);
return (its == m_targets.end()) ? nullptr : itr.value();
}
When I compile I get the following errors which I am struggling to see what is wrong:
C2663: 'QMap<QString, TargetInfo *>::insert': 2 overloads have no legal conversion for 'this' pointer
C2440: 'initialising': cannot convert from 'QMap<QString, TargetInfo *>::const_iterator' to 'QMap::<QString, TargetInfo *>::iterator'
No constructor could take the source type, or constructor overload resolution was ambiguous
For the second error change
QMap<QString, TargetsInfo*>::iterator itr = ...
to
QMap<QString, TargetsInfo*>::const_iterator itr = ...
Your getTarget method is const so m_targets.find returns a const iterator (otherwise you could change m_targets inside your supposedly const method).
For the first error, remove const from your addTarget method. Obviously a method which adds items to m_targets should not be const.
I have this code here:
class MemcpyMatcher : public MatchFinder::MatchCallback
{
public:
MemcpyMatcher(map<string, Replacements> * replacements)
: replacements(replacements) {}
/* Callback method for the MatchFinder.
* #param result - Found matching results.
*/
virtual void run(const MatchFinder::MatchResult& result)
{
const CallExpr* call_expr = result.Nodes.getNodeAs<CallExpr>("memcpy_call");
if (call_expr != NULL) {
const Expr* voidp_dest = call_expr->getArg(0)->IgnoreImplicit();
const Expr* voidp_src = call_expr->getArg(1)->IgnoreImplicit();
const Expr* size_t_n = call_expr->getArg(2)->IgnoreImplicit();
voidp_dest->dump();
}
private:
map<string, Replacements>* replacements;
// Add other variables here as needed.
};
This is the output of the voidp_dest->dump(); statement:
UnaryOperator 0x2148d48 'int *' prefix '&'
`-DeclRefExpr 0x2148cf8 'int' lvalue Var 0x21480c0 'number' 'int'
In the source code, the expression that I'm grabbing looks like this: &number.
I want to get the DeclRefExpr out of the UnaryOperator, in order to turn it into a string and get the name of the variable out. I don't know how to do that.
For anybody who is still searching for answer:
const DeclRefExpr* decl_ref = nullptr;
if (auto unary = dyn_cast<UnaryOperator>(expr)) {
if (unary->getOpcode() == UnaryOperator::Opcode::UO_AddrOf) {
unsigned count = 0;
// there will be only one child
for (auto child : unary->children()) {
decl_ref = dyn_cast<DeclRefExpr>(child);
}
}
}
Another way to do this same task with less LOC,
DeclRefExpr* ref = nullptr;
if(auto UnOp = dyn_cast<UnaryOperator>(expr)) {
ref = dyn_cast<DeclRefExpr>(UnOp->getSubExp());
}
I am just starting my adventure in the land of C++, so this may be a silly question. I am getting the following error from my compiler.
Run.cc:56: error: no matching function for call to ‘sphereDetect::getArrayPtr() const’
/spheredetect.hh:18: note: candidates are: const G4long (* sphereDetect::getArrayPtr())[36][72][60]
my Run.hh is:
#include "spheredetect.hh"
#include "G4Run.hh"
#include "globals.hh"
class G4Event;
/// Run class
///
class Run : public G4Run
{
public:
Run();
virtual ~Run();
// method from the base class
virtual void Merge(const G4Run*);
void AddEdep (G4double edep);
// get methods
G4double GetEdep() const { return fEdep; }
G4double GetEdep2() const { return fEdep2; }
private:
G4double fEdep;
G4double fEdep2;
sphereDetect scatter;
};
my Run.cc is:
#include "Run.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
Run::Run()
: G4Run(),
fEdep(0.),
fEdep2(0.),
scatter()
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
Run::~Run()
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void Run::Merge(const G4Run* run)
{
const Run* localRun = static_cast<const Run*>(run);
fEdep += localRun->fEdep;
fEdep2 += localRun->fEdep2;
arr* scatterPointer = localRun->scatter.getArrayPtr();
scatter.sphereMerge(scatterPointer);
G4Run::Merge(run);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void Run::AddEdep (G4double edep)
{
fEdep += edep;
fEdep2 += edep*edep;
}
and my sphereDetect.hh is:
typedef G4long arr[36][72][60];
class sphereDetect
{
public:
sphereDetect();
~sphereDetect();
const arr* getArrayPtr() {return &scatterArray;}
void sphereMerge(arr*);
void createHit(G4ThreeVector,G4double);
protected:
void storeHit(G4int,G4int,G4int);
G4int findAngNS(G4ThreeVector);
G4int findAngEW(G4ThreeVector);
G4int findEnergy(G4double);
void sphereSave();
private:
G4long scatterArray[36][72][60];
};
I am fairly lost as to how to resolve this. Is it in the way i construct or call the sphereDetect class? The one thing that is certain is that the input for the Run.Merge is required to be that input(based on the previous code).
Any help is greatly appreciated,
Will
You're short a const.
const arr* getArrayPtr() {}
Means "this returns a const pointer".
const arr* getArrayPtr() const {}
Means "this returns a const pointer, and can be called on a const object". Otherwise, the compiler can't tell that getArrayPtr() doesn't want to modify the object on which it's called.
Since localRun is const, it's member localRun->scatter is const, too.
The compiler is looking for a definition of getArrayPtr() which declares that it will not modify the object and thus is safe to call on a const object. This is done by putting the const after the rest of the function signature, just like G4double GetEdep() const has it.
Trying to create an asyncronous Observer pattern is causing a compiler error C3867, which I am clueless how to resolve it. The sample code snippet is as follows
class Subject;
class Observer
{
public:
virtual void notify(Subject* s) = 0;
virtual ~Observer() {};
};
class Subject
{
std::map<std::string, Observer *> observers;
protected:
void notify_observers()
{
std::map<std::string, Observer *>::iterator iter;
for (iter = observers.begin(); iter != observers.end(); ++iter) {
void (Observer::*notify)(Subject *) = iter->second->notify;
std::async(std::launch::async, notify, this);
}
}
public:
virtual ~Subject() {};
void observer(std::string id, Observer* o)
{
observers[id] = o;
}
};
template<typename Iter, typename type>
class Sort : public Observer {
public:
virtual void notify(Subject* s)
{
TestSort<Iter> *a;
a = dynamic_cast<TestSort<Iter> *>(s);
std::vector<type> temp(a->beg(), a->end());
sort(temp->beg(), temp->end());
}
};
template<typename Iter, typename type>
class InsertionSort : public Sort<Iter, type>
{
void sort(Iter beg, Iter end) {
for (Iter i = beg; i != end; ++i)
std::rotate(std::upper_bound(beg, i, *i), i, i+1);
}
};
int main ()
{
std::vector<double> data(100);
std::generate(data.begin(), data.end(), [](){return rand() % 500;} );
auto ts = TestSort<std::vector<double>::iterator >(data.begin(), data.end());
auto is = new InsertionSort<std::vector<double>::iterator, double >();
//.................
ts.observer("InsertionSort", is);
//.........................
ts.Triggerd();
return 0;
}
Though I understand the error
error C3867: 'Observer::notify': function call missing argument list; use '&Observer::notify' to create a pointer to member
Yet in this context I cannot figure out, how to resolve it.
In this context, if notify would had been a simply addreesable member function, instead of
void (Observer::*notify)(Subject *) = iter->second->notify;
I could have simply write
void (Observer::*notify)(Subject *) = &Observer::notify;
But notify is a polymorphic function and I cannot address the right function during compile time.
Please suggest how should I process
You don't need to figure out the right function during compile time, just as you don't have to figure it out for regular virtual function call. Just use &Observer::notify. The right function is selected at the time of call, not at the time of taking its address.
Change:
void (Observer::*notify)(Subject *) = iter->second->notify;
std::async(std::launch::async, notify, this);
To:
void (Observer::*notify)(Subject *) = &Observer::notify;
std::async(std::launch::async, std::mem_fun(notify), iter->second, this);
When you call a method, you need both the pointer-to-instance and arguments. The standard syntax is rettype retval = instance->method(arg);, but std::mem_fun will return a functor you can use like rettype retval = std::mem_fun(&InstanceType::method)(instance, arg); -- it makes the implicit this pointer passed to a member function explicit.
From a pointer to a virtual method, plus an object pointer, std::mem_fun can figure out which instance of the virtual method you should call.
A similar thing can be done with a bind or a lambda. Here is a roughly equivalent call using lambda syntax:
Observer* observer = iter->second;
std::async(std::launch::async, [observer,this]() { observer->notify(this); } );
See the comment below: you don't have to use std::mem_fun, async will do it for you. You do have to pass the instance pointer of the member function as the next argument still.
As part of an assignment for a data structures class, I am trying to get this over a decade-old code to actually work. The code is found here: http://www.brpreiss.com/books/opus4/
(And to all of the users here who are horrified at such bad design, take heart - this is a homework assignment where the goal is ostensibly to get someone else's code to work. I am not advocating its use.)
Here, the author defined the class Stack and its associated Iterator:
#ifndef STACK_H
#define STACK_H
#include "linkList.h"
#include "container.h"
class Stack : public virtual Container
{
public:
virtual Object& Top () const = 0;
virtual void Push (Object&) = 0;
virtual Object& Pop () = 0;
};
class StackAsLinkedList : public Stack
{
LinkedList<Object*> list;
class Iter;
public:
StackAsLinkedList () : list() {}
~StackAsLinkedList() { Purge(); }
//
// Push, Pop and Top
//
void Push(Object& object);
Object& Pop() override;
Object& Top() const override;
int CompareTo(Object const& obj) const;
//
// purge elements from, and accept elements onto, the list
//
void Purge();
void Accept (Visitor&) const;
friend class Iter;
};
class StackAsLinkedList::Iter : public Iterator
{
StackAsLinkedList const& stack;
ListElement<Object*> const* position;
public:
Iter (StackAsLinkedList const& _stack) : stack(_stack) { Reset(); }
//
// determine whether iterator is pointing at null
//
bool IsDone() const { return position == 0; }
//
// overloaded dereference and increment operator
//
Object& operator*() const;
void operator++();
void Reset() { position = stack.list.Head(); }
};
#endif
I am not sure what the objective is here, because trying to instantiate a StackAsLinkedList::Iter will predictably give an error because it is private. Furthermore, the author doesn't use the iterator he just implemented for stack in the below example, which instead uses the iterator defined in the parent class of Stack called Container to traverse the stack and print the values:
StackAsLinkedList stack;
Iter& i = stack.NewIterator();
stack.Push(*new Int(1) ); //type "Int" is a Wrapper for primitive "int"
stack.Push(*new Int(2) );
...
while ( ! outIter.IsDone() )
{
cout << *outIter << endl;
++outIter;
}
...
But when he creates stack.NewIterator(), a look at the method call in Container shows:
virtual Iterator& NewIterator () const { return *new NullIterator (); }
So the conditional in the while statement will always fail and thus the body will never execute.
This leads me to believe that I should be implementing another NewIterator method for Stack, but I am not sure what the return value should be ( *new StackAsLinkedList::Iter(_stack) ?).
Any ideas?
Adding the following method in StackAsLinkedList seemed to clear up the problem:
Iterator& StackAsLinkedList::NewIterator() const
{
return *new Iter(*this);
}
Also, the order of assignment in main() was also an issue. This seemed to correct it:
StackAsLinkedList stack;
stack.Push(*new Int(1) ); //type "Int" is a Wrapper for primitive "int"
stack.Push(*new Int(2) );
...
Iter& i = stack.NewIterator();
while ( ! outIter.IsDone() )
{
cout << *outIter << endl;
++outIter;
}
I realize that this solution is not ideal - ideally I should refactor or better yet just start over (or just use STL). But as I said above, the goal was to just get this stuff to compile and work within a limited time-frame. So to echo what others have said: please don't use this code!