Sign in to follow this  
Concentrate

Help with compile error(C++)

Recommended Posts

I am trying to get the following to work( for practice ). Kinda psuedocode-ish
[code]
<template T>
class Foo{
//...
template<typename Func1>
void apply(const Func1&){
for each element in current Foo
Func1(*current)
}
void addFoo(const T& val){ ... } //add Node with value val.
Foo(const Foo<T>& f){
_fooSize = f._fooSize;
f.apply( std::mem_fun( &(Foo<T>::addObject)); //Problem arises or starts here I guess.
};
[/code]

I wanted to use the apply algorithm in f.apply to call the current addObject with all values in f. This is the compile error:
[code]
error: no match for call to '(const std::mem_fun1_ref_t<void, List<int>, const int&>) (int&)'
note: candidates are: _Ret std::mem_fun1_ref_t<_Ret, _Tp, _Arg>::operator()(_Tp&, _Arg) const [with _Ret = void, _Tp = List<int>, _Arg = const int&]
[/code]

I'm not quite sure how to solve this. Any help would be appreciated.

Share this post


Link to post
Share on other sites
I'm not quite sure I understand what you're trying to do, but it looks like you might be forgetting to give the function a this pointer.
It would be helpful if I could compile your code myself, but without all the code that's not an option.

Here's some code which shows how you can use std::mem_fun, maybe it will help you solve your problem.

[code]
template <typename T>
class Foo
{
public:
void foo(T i)
{
//Make sure printf won't break in case T isn't an int.
static_assert(std::is_integral<T>::value, "T must be an integer");

printf("foo(%u)\n", i);
}

template <typename Func>
void runMemberFunction(Func func, T i)
{
//Run function with the this pointer as the first argument.
func(this, i);
}
};

int main(int, const char**)
{
Foo<int> myFoo;
auto fooFunc = std::mem_fun(&Foo<int>::foo);
myFoo.runMemberFunction(fooFunc, 42);

//Run the function with myFoo as the first argument (simulating the this pointer).
fooFunc(&myFoo, 42);

return 0;
}
[/code]

Share this post


Link to post
Share on other sites
example:
[code]
#include <functional>
#include <iostream>
using namespace std;

template<typename T>
class Foo{
private:
struct FooNode{
T val;
FooNode *prev, *next;
FooNode(const T& val = T(), FooNode *p = 0, FooNode *n =0): val(val),prev(p),next(n){};
};
private:
FooNode *_head, *_tail;
public:
Foo(): _head(0),_tail(0){}

//Copy-CTOR
//I want to call the pushBack function, hence creating new object from the given obj's elements
Foo(const Foo<T>& obj){
obj.apply(mem_fun(&Foo<T>::pushBack));
}
void pushBack(const T& val){
if (_head == 0) {
_tail = _head = new FooNode(val);
}else{
FooNode* tmp = _tail;
tmp->next = new FooNode(val,_tail,0);
_tail = tmp;
}
}

template<typename Func1>
void apply(const Func1& op)const{
for (FooNode *curr = _head; curr; curr = curr->next) {
op(curr->val);
}
}
};

template<typename T> void print(const T& arg){ cout << arg << " "; }

int main(){
Foo<int> obj;
obj.pushBack(4);
obj.pushBack(3);
obj.apply(print<int>);

Foo<int> job(obj);

//LET OS DELETE MEMORY, don't want to write it now, note I can't use additional dependencies
return 0;
}
[/code]

Share this post


Link to post
Share on other sites
You need to bind the member function to an object instance. One method:
[code]
Foo(const Foo<T>& obj){
obj.apply(std::bind(std::mem_fn(&Foo<T>::pushBack), this, std::placeholders::_1));
}
[/code]

Share this post


Link to post
Share on other sites
[quote name='SiCrane' timestamp='1318783249' post='4873148']
You need to bind the member function to an object instance. One method:
[code]
Foo(const Foo<T>& obj){
obj.apply(std::bind(std::mem_fn(&Foo<T>::pushBack), this, std::placeholders::_1));
}
[/code]
[/quote]

is there anyway I can do this without using the new features?

Share this post


Link to post
Share on other sites
You could use boost or create your own function object that acts as a closure for the bound member function. Unfortunately, the C++03 standard library feature that would theoretically help with this, std::bind1st, doesn't play nicely with member functions that have reference parameters like your pushBack() member function. If you really do want to use that then you can alter your pushBack() member function to accept its argument by value and use:
[code]
obj.apply(bind1st(mem_fun(&Foo<T>::pushBack), this));
[/code]
Also, you might want to initialize the pointers to null before you call the apply() member function.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this