problem of inheriting from a STL function class

Sep 14, 2010 at 4:49am
My program can't be compiled through by GCC 4.3.3. The part of the program causing the problem is simplified as the following short code.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
#include <functional>

using namespace std;

class op : public unary_function<int,int> {
public:
	int operator()(int) {}
};

class test {
public:
	void func(unary_function<int,int> & o = op()) {}
};

int main()
{
} 

The compiler complained that the type of the default argument is not comply with the type of the parameter. I don't know why this happened. Please help me out. Thanks!
Sep 14, 2010 at 5:16am
closed account (1yR4jE8b)
The C++ standard states that you cannot pass temporary objects as parameters through non-const references. This includes default arguments.

Changing the parameter to a const references fixes the compilation error:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
#include <functional>

using namespace std;

class op : public unary_function<int,int> {
public:
	int operator()(int) {}
};

class test {
public:
	void func(const unary_function<int,int> & o = op()) {}
};

int main()
{
} 

Sep 14, 2010 at 6:56am
I have made the modifications as the following code, but it can't still be compiled correctly. The compiler complained that "no match function for (const std::unary_function<int, int>) (int)".
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include <functional>

using namespace std;

class op : public unary_function<int,int> {
public:
	int operator()(int) const {}
};

class test {
public:
	void func(const unary_function<int,int> & o = op()) { int a = o(1); }
};

int main()
{
	test t;
	t.func();
}

What is the problem left in this code. Thanks!
Last edited on Sep 14, 2010 at 6:57am
Sep 14, 2010 at 8:31am
The problem is that unary_function is not a virtual class and doesn't overload the operator ()
Functors are usually used with templates, this should do what you want:

1
2
3
4
5
6
// will deduce the type of the function from the argument passed by the caller
template < typename UnaryFunction >
    void func(const UnaryFunction & o ) { int a = o(1); }

// default value
void func( ) { int a = op(1); }
Sep 14, 2010 at 9:01am
I was going to say that:

const unary_function<int,int> & o = op()) //is an error

because op is not type of unary_function<int,int>

You can change the func function to use templates
or jsut change it to void func( op & o = op())
Sep 14, 2010 at 5:33pm
The original example looks really fishy to me. I'd love to know what the OP is trying to do. I don't understand the application of that concept. What is the purpose of the test class?
Sep 14, 2010 at 10:55pm
The original purpose is to enable a member function of a class to calculate a objective result through several optional methods which accepts the same type of input and output. What's wrong with it?
Sep 14, 2010 at 11:27pm
Sounds like the strategy pattern could be useful here...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include <iostream>
using namespace std;

struct Add
{
    int calculate(int a, int b)
    {
        return a+b;
    }
};

struct Sub
{
    int calculate(int a, int b)
    {
        return a-b;
    }
};

template <class CalcMethod>
struct Calculator: public CalcMethod
{
    int a;
    int b;

    Calculator(int a_, int b_):a(a_),b(b_){}

    int calculate()
    {
        return CalcMethod::calculate(a,b);
    }
};

int main()
{
    Calculator<Add> add(1,2);
    Calculator<Sub> sub(3,1);

    cout << "1+2=" << add.calculate() << endl;
    cout << "3-1=" << sub.calculate() << endl;

    cout << "\nhit enter to quit...";
    cin.get();
    return 0;
}

Or... do you want to be able to change the operation during run-time?
Last edited on Sep 14, 2010 at 11:35pm
Sep 15, 2010 at 1:16am
Thanks for your reply. I prefer STL function class which works the same way as you mentioned. ;-p
Sep 15, 2010 at 2:16am
hank you so much for the post. It's really informative!




__________________
[url=http://moviesonlineworld.com]watch free movies online[/url]
Sep 15, 2010 at 2:17am
closed account (1yR4jE8b)
I'm curious to know what compilers was used to compile the code that I proposed initially as mine compiles just fine:

tyler@tyler-desktop:~/Desktop$ g++ --version
g++ (Ubuntu/Linaro 4.4.4-14ubuntu3) 4.4.5
Copyright (C) 2010 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

tyler@tyler-desktop:~/Desktop$ cat functor.cpp
#include <iostream>
#include <functional>

using namespace std;

class op : public unary_function<int,int> {
public:
int operator()(int) {}
};

class test {
public:
void func(const unary_function<int,int> & o = op()) {}
};

int main()
{
}
tyler@tyler-desktop:~/Desktop$ g++ functor.cpp
tyler@tyler-desktop:~/Desktop$


Sep 15, 2010 at 2:53am
A call of operator() method of object o within func function will cause the compiling failure for my compiler. But, it doesn't matter now. The problem has been solved by template.
Last edited on Sep 15, 2010 at 2:54am
Topic archived. No new replies allowed.