What is the problem with this code ? this code is giving me lots of syntax errors. Also I would like to know why functors are used in C++.
class f
{
public:
int operator(int a) {return a;}
} obj;
int main()
{
cout << obj(0) << endl;
}
You're missing an extra pair of parenthesis when declaring operator(). The name of the function is operator(), and it still needs the list of parameters after it. Thus it should look like:
int operator()(int a) {return a;}
Function objects (a.k.a. functors) like this are typically used where you'd use a pointer to a function. However, they have the advantage that they can use inheritance and they encapsulate state as well. Often, well designed class or function templates will be able to use them almost interchangeably with function pointers. However, a good optimizer can typically produce better code when a template object is used.
For a fairly sophisticated example of how you might use function objects, have a look at expression templates.
Here's a small, somewhat contrived example of how they can use inheritance:
struct unary_int_func {
virtual int operator()(int i) = 0;
};
struct negate : public unary_int_func {
int operator()(int i) {return -i;}
};
struct one_plus : public unary_int_func {
int operator()(int i) {return i+1;}
};
void show_it(unary_int_func &op, int v) {
cout << op(v) << endl;
}
In this case, we create a base class with the operator as a pure virtual function. Then we derive to concrete classes that implement it. Code such as show_it() can then use any instance of a class derived from this base. While we could just have used a pointer to a function that takes an int and returns an int, this is more typesafe. Code that uses the function pointer would accept any such function pointer, whereas this way we can define a whole new hierarchy that maps an int to an int:
struct a_different_base_class {
virtual int operator()(int i) = 0;
};
but instances of this would not be interchangeable with instances of unary_int_func.
As for state, consider a running sum function:
struct running_sum : public unary_int_func {
int total;
running_sum() : total(0) {}
int operator()(int i) {return total += i;}
};
int main()
{
running_sum s;
cout << s(1) << endl;
cout << s(2) << endl;
cout << s(3) << endl;
cout << s(4) << endl;
}
Here, the instance of running_sum keeps track of the total. It will print out 1, 3, 6 and 10. Pointers to functions have no such way of keeping state between distinct invocations. SGI's STL page on function objects has a similar example to my running sum one, but shows how you can easily apply it to a range of elements in a container.
Functors are basically functions with states. Their biggest usage is in STL and Boost libraries. For example std::sort takes a type of functor called Comparator. In this context, perhaps a function object could have been passed instead but functor offers more flexibility by means of the data members you can have and manipulate with subsequent calls to the same functor. Functors are also used to implement C++ callbacks.
As you already have figured out the issue in your operator overloading code, I would rather try to address your doubt regarding functors.
Functor is a short for 'function pointer'.
These are widely used to provide a handle to customize the behavior of an algorithm, for example the sorting algorithms in STL use functor as parameter and the user (programmer) can implement the function to tell the algorithm the result of comparison for 2 elements.
because int operator(int) is effectively equal to int int #something_missing_here#(int)
operator is a reserved keyword and not qualifier as valid function identifier/name when used alone.
I would say it is used to make compiler understand that given expression are function declaration despite the invalid identifiers used (c++ only allow alphabet and underscore as first character in naming)
A functor is an object (instance of class or struct) that typically overloads the operator(). The difference between a functor and a normal function is that because a functor is an object, it can maintain state between calls.
Because a functor is an object, rules of inheritance apply as well and you can use this to your advantage.
A functor is also useful when you use the STL. std::sort, std::for_each, etc allow you to process the contents of an entire container (arrays included). Here's an example from cplusplus.com:
// for_each example
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
void myfunction (int i) {
cout << " " << i;
}
struct myclass {
void operator() (int i) {cout << " " << i;}
} myobject;
int main () {
vector<int> myvector;
myvector.push_back(10);
myvector.push_back(20);
myvector.push_back(30);
cout << "myvector contains:";
for_each (myvector.begin(), myvector.end(), myfunction);
// or:
cout << "\nmyvector contains:";
for_each (myvector.begin(), myvector.end(), myobject);
cout << endl;
return 0;
}
Try this:
class f
{
public:
int operator(int a) {return a;}
};
int main()
{
f obj;
cout<<obj(0)<<endl;
}
Related
I would like to perform a down casting at execution time.
For what I read, if I want to do it, I need to compare the typeid of my polymorphic pointer with those of my derived classes, then do the casting in the correct type.
Plus, let's assume that I have a large number of derived classes.
This implies I have to write a long switch or list of if.
I would like to reduce this effort by using a list of classes to check.
This could look like:
#include <string.h>
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <vector>
#include <map>
using namespace std;
class BaseShapes
{
virtual int run() = 0;
};
class ClassRectangle : public BaseShapes
{
int run()
{
std::cout << "I am a Rectangle. " << std::endl;
return 0;
}
float get_length () {return 12.4;};
float get_width() {return 6.2;};
};
class ClassCircle : public BaseShapes
{
int run()
{
std::cout << "I am a Cricle. " << std::endl;
return 0;
}
float get_diameter() {return 5.3;};
};
float function_only_for_Rectangle(ClassRectangle *rectangle)
{
// a function coming from a library that I cannot touch and that requires a derived type.
// But for the example I do something dummy!
return rectangle->get_length()
};
auto downcast_function (auto *p)
{
enum ListOfTypes {
ClassCircle,
ClassRectangle,
// and a lot more differents classes
};
for ( int fooInt = ClassCircle; fooInt < ClassRectangle; fooInt++ )
{
ListOfTypes fooItem = static_cast<ListOfTypes>(fooInt);
if (typeid(p) == typeid(fooItem))
{
auto pCasted =dynamic_cast<fooItem>(p);
return pCasted;
}
}
std::cout<< "downcast_function warning: no typeid is matching !" << std::endl;
return p;
};
int main(void)
{
// Beginning of main.
cout << "(Start)" << endl;
std::unique_ptr<BaseShapes> Shape1(new ClassRectangle());
auto p=Shape1.get();
//function_only_for_Rectangle(p); // not working since p is of type BaseShapes*
auto pbis=downcast_function(p); // should be of type ClassRectangle*
function_only_for_Rectangle(pbis);
// End of the main.
cout << "(End) " << endl;
return 0;
}
// EoF
So how can I write the downcast_function ? Or in other words, how can I iterate over a list of class types in order to make a typeid comparison and a casting ?
More details:
I agree that in this dummy example, I could simply override a function for each derived class and that is a much better way to deal with polymorphism. But I need to downcast, this is a constrain coming from a more complex problem where they are things that I am not allowed to changed. So, the question here is not why downcast but how.
To give a bit more details about my constrains are:
To start from a base pointer.
Get a derived pointer and give it to an external function (here called function_only_for_Rectangle, so I cannot modify this function).
I cannot do a simple and direct dynamic_cast<ClassRectangle>(p) because the type of p (or equivalently Shape1) will change at running time. This means that Shape1 can have "randomly" any derived type from BaseShapes. So I need something "automatic" and this is why I was thinking about iterate over all derived types and downcast according to the typeid match (but I am open to better ideas).
All the classes can modified if needed.
You say "polymorphic" but what you want to do is the opposite of it.
Instead of trying to work against polymorphism you could actually use it. If all subclasses have their own implementation of a virtual function then the caller does not need to care what the actual dynamic type of the object is. That is runtime polymorphism in a nutshell.
I suppose the naming for run is only for the example. Give it a better name, supply a default implementation in the base class, implement specific behavior in ClassRectangle and let the caller call it. No need to cast.
class BaseShapes
{
virtual int do_something_rectangly() { return 0;}
~virtual BaseShapes() = default;
};
class ClassRectangle : public BaseShapes
{
int do_something_rectangly() override
{
std::cout << "I am a Rectangle. " << std::endl;
return 0;
}
};
class ClassCircle : public BaseShapes
{
// does not override do_something_rectangly()
};
int function_for_any_base_shape(BaseShapes& s)
{
return s.do_something_rectangly();
};
int main(void)
{
// Beginning of main.
cout << "(Start)" << endl;
std::unique_ptr<BaseShapes> Rec1(new ClassRectangle());
function_for_any_base_shape(*pbis);
cout << "(End) " << endl;
return 0;
}
Concerning your edit:
I cannot do a simple and direct dynamic_cast(p) because the type of p (or equivalently Shape1) will change at running time. This means that Shape1 can have "randomly" any derived type from BaseShapes. [...]
Either I misunderstand what you wrote completely or you misunderstand how dynamic_cast works. dynamic_cast does already check what the dynamic type of the object is:
BaseShapes* b1 = new ClassCircle;
if(ClassRectangle* d = dynamic_cast<ClassRectangle*>(b1))
{
// cast is sucessfull
function_only_for_Rectangle(d);
} else {
// dynamic type of b1 is not ClassRectangle
}
To call function_only_for_Rectangle you do not need to be able to cast to all subtypes of ClassBase. You only need to dynamic_cast to a pointer to ClassRectangle and check if the cast was sucesfull.
Basically, I am implementing a container class. I need to create a method which sorts the data according to the comparator function/functor which must be passed with the sort request. Since declaration and definition of the method are in different files(.h and .cpp) using templates becomes a problem (and I don't have much experience using them). In other words, I want to make a method:
void sort(function/functor f);
and I don't know how to define the function. So, is there any solution to this problem?
If you know the signature of the function/functor to be passed[*], you can use std::function. Or boost::function if you don't have C++11. So for a comparator it would be:
void sort(std::function<bool(const Element&, const Element&)> f);
where Element is the type of the elements of the container.
Failing that you could define a class with a virtual compare function, and allow callers to derive from it with their own class. It's more work for callers, but that's exactly what std::function provides: a way for callers to not have to do that.
Two warnings:
make sure there's really a good reason for the implementation of your container not to be in the header file. All of the standard containers are implemented in header files, and that mostly works OK.
make sure there's really a good reason for you to implement a sort function. Standard containers only have sort functions where std::sort doesn't work: std::list and std::forward_list.
[*] Actually std::function doesn't require the exact same signature. You just say the types you want to call it with and the type you want to convert the return value to. So if you call it with two ints and the caller provides a function that takes two longs, then that's fine. The arguments are converted just like the function call would without any std::function.
This is generally done with templates. Like this:
#include <iostream> // For example output only.
template <typename F>
void sort(F&& pred) {
pred(123);
}
void normal_func(int v) {
std::cout << "normal_func(" << v << ")\n";
}
struct my_pred {
void operator()(int v) const {
std::cout << "my_pred(" << v << ")\n";
}
};
int main() {
sort([](int v) { std::cout << "Called lambda func with " << v << '\n'; });
sort(normal_func);
sort(my_pred());
}
If, however, templates cannot be used, then your best bet would be to use polymorphic function wrapper like std::function (or boost::function, or you can write your own simple version).
Alternatively, you can use a hardcore C-style regular function along with a void pointer where user can save their context. For example, like qsort(). Though I'd try not to go there if possible.
Here is an example using std::function:
#include <iostream> // For example output only.
#include <functional> // For std::function.
void sort(const std::function<void(int)>& pred) {
pred(123);
}
void normal_func(int v) {
std::cout << "normal_func(" << v << ")\n";
}
struct my_pred {
void operator()(int v) const {
std::cout << "my_pred(" << v << ")\n";
}
};
int main() {
sort([](int v) { std::cout << "Called lambda func with " << v << '\n'; });
sort(normal_func);
sort(my_pred());
}
Hope it helps.
You can use std::function as suggested in Steve Jessop's answer but in this case I think you should consider making your sort function a template function as in Vlad's answer. A sort function has to call the comparator many times and there will be noticeable overhead to using std::function in this situation.
The easiest solution is to use a template:
class C
{
template<typename T>
void sort(T func)
{
func(12,45); // Will compile as long as your function/functor
} // Can take two integers as parameters.
}; // NOTE: or integers can be converted into your parameters.
If you want to specify using old C notation.
typedef void (*FUNC_TYPE)(int, int); // declares a function pointer type.
// returns void takes two integers.
class C
{
void sort(FUNC_TYPE func)
{
func(12,45); // Compiles only if the function
} // matches the exact type.
};
The C++11 way
class C
{
void sort(std::function<void(int,int)> func)
{
func(12,45); // Will match any func/functor that
// will return a void and takes two
} // integers.
};
I have a question about the for_each in vector, the code is following:
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
struct myclass {
void operator() (int i) {cout << " " << i;}
} myobject;
int main () {
vector<int> myvector(3,4);
cout << "\nmyvector contains:";
for_each (myvector.begin(), myvector.end(), myobject);
cout << endl;
return 0;
}
should the third argument of for_each() be a function name?
if we pass the name of the struct, how does this works?
This is a functor.
std::for_each is a function template that basically expands to this:
for (iter = myvector.begin(); iter != myvector.end(); ++iter)
{
myobject(*iter);
}
So myobject can either be a function pointer, or it can be an object with an overload for operator().
The third argument of for_each can be anything that behaves like a function, i.e. that can be invoked like x(). Since your struct overloads operator(), it has precisely this behaviour.
Classes which overload the ()-operator are called "functors" or "function objects". Their power lies in the fact that you can store additional data (e.g. accumulators or inital values) in the class members while still behaving like an ordinary function.
Not necessarily. for_each expects an object that can be called like a function (a functor). In other words, an object that overloads operator()(T) where T is the type of the values held in the container on which for_each is applied.
You are not passing a type or (quote) "name of a struct", but rather an object. The syntax
struct Foo {
} foo;
actually declares the type Foo and on object foo of type Foo.
Passing function objects instead of function pointers is prefered. See also
this about why.
The code is pretty well explained where, I think, you found it:
The source of the code.
The example on the site looks like this:
// for_each example
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
void myfunction (int i) {
cout << " " << i;
}
struct myclass {
void operator() (int i) {cout << " " << i;}
} myobject;
int main () {
vector<int> myvector;
myvector.push_back(10);
myvector.push_back(20);
myvector.push_back(30);
cout << "myvector contains:";
for_each (myvector.begin(), myvector.end(), myfunction);
// or:
cout << "\nmyvector contains:";
for_each (myvector.begin(), myvector.end(), myobject);
cout << endl;
return 0;
}
It's not a function name, it's a function object (functor).
You can either do this manually yourself by defining a class with suitable operator() implementation, or wrap a function as a functor using Boost.Function or similar.
Note that there is a subtle issue here. If you define your operator() as you have here, the code works, but cannot be used to update the vector elements. If you wish to update in place, you need to define instead as (for example):
void operator() (int& i) { i *= 2; }
This is more typically how functors are defined - arguments are passed by reference rather than by value.
Since you are overloading operator () (int) for myclass, the function name is resolved from the struct itself. See for_each for more info.
This is a sequel to a related post which asked the eternal question:
Can I have polymorphic containers with value semantics in C++?
The question was asked slightly incorrectly. It should have been more like:
Can I have STL containers of a base type stored by-value in which the elements exhibit polymorphic behavior?
If you are asking the question in terms of C++, the answer is "no." At some point, you will slice objects stored by-value.
Now I ask the question again, but strictly in terms of C++11. With the changes to the language and the standard libraries, is it now possible to store polymorphic objects by value in an STL container?
I'm well aware of the possibility of storing a smart pointer to the base class in the container -- this is not what I'm looking for, as I'm trying to construct objects on the stack without using new.
Consider if you will (from the linked post) as basic C++ example:
#include <iostream>
using namespace std;
class Parent
{
public:
Parent() : parent_mem(1) {}
virtual void write() { cout << "Parent: " << parent_mem << endl; }
int parent_mem;
};
class Child : public Parent
{
public:
Child() : child_mem(2) { parent_mem = 2; }
void write() { cout << "Child: " << parent_mem << ", " << child_mem << endl; }
int child_mem;
};
int main(int, char**)
{
// I can have a polymorphic container with pointer semantics
vector<Parent*> pointerVec;
pointerVec.push_back(new Parent());
pointerVec.push_back(new Child());
pointerVec[0]->write();
pointerVec[1]->write();
// Output:
//
// Parent: 1
// Child: 2, 2
// But I can't do it with value semantics
vector<Parent> valueVec;
valueVec.push_back(Parent());
valueVec.push_back(Child()); // gets turned into a Parent object :(
valueVec[0].write();
valueVec[1].write();
// Output:
//
// Parent: 1
// Parent: 2
}
You certainly can't have a polymorphic array (or vector). The requirement that the elements of an array be stored contiguously in memory is fundamentally incompatible with the fact that different derived class types may have different sizes.
None of the standard library containers allow for storing objects of different derived class types in a single container.
Just for fun, based on James's comment about a template-based system, I came up with this Vector-like implementation. It's missing lots of features, and may be buggy, but it's a start!
#include <iostream>
#include <vector>
#include <boost/shared_ptr.hpp>
template <typename T>
class Vector
{
public:
T &operator[] (int i) const { return p[i]->get(); }
template <typename D>
void push_back(D &x) { p.push_back(ptr_t(new DerivedNode<D>(x))); }
private:
class Node
{
public:
virtual T &get() = 0;
};
template <typename D>
class DerivedNode : public Node
{
public:
DerivedNode(D &x) : x(x) {}
virtual D &get() { return x; }
private:
D x;
};
typedef boost::shared_ptr<Node> ptr_t;
std::vector<ptr_t> p;
};
///////////////////////////////////////
class Parent
{
public:
Parent() : parent_mem(1) {}
virtual void write() const { std::cout << "Parent: " << parent_mem << std::endl; }
int parent_mem;
};
class Child : public Parent
{
public:
Child() : child_mem(2) { parent_mem = 2; }
void write() const { std::cout << "Child: " << parent_mem << ", " << child_mem << std::endl; }
int child_mem;
};
int main()
{
Vector<Parent> v;
v.push_back(Parent());
v.push_back(Child());
v[0].write();
v[1].write();
}
First of all, your requirements are still not perfectly clear. I will assume that you want "inline storage" for the container; so, for example, in a "polymorphic" vector, all elements would be adjacent in memory (with only padding in between as needed for correct alignment).
Now, it is possible if you're willing to provide an exhaustive list of all types that you're going to put into the container at compile-time. The most straightforward implementation would be to use a union of all possible types as the type of the backing array - that would ensure enough size and proper alignment, and same O(1) access by index, at the cost of some wasted space on elements of smaller-size types. I can go into this with more detail if you want.
If the list of types is now known in advance, or if you do not want that kind of overhead, then you'd have to maintain a separate index of pointers (or offsets from the beginning of the backing store) to elements, so that you can do O(1) access. Also, given the alignment issues, I'm not sure if you could even do that in fully portable C++03, though you definitely can in C++0x.
Is there a way to make a non-resizeable vector/array of non-reassignable but mutable members? The closest thing I can imagine is using a vector<T *> const copy constructed from a temporary, but since I know at initialization how many of and exactly what I want, I'd much rather have a block of objects than pointers. Is anything like what is shown below possible with std::vector or some more obscure boost, etc., template?
// Struct making vec<A> that cannot be resized or have contents reassigned.
struct B {
vector<A> va_; // <-- unknown modifiers or different template needed here
vector<A> va2_;
// All vector contents initialized on construction.
Foo(size_t n_foo) : va_(n_foo), va2_(5) { }
// Things I'd like allowed: altering contents, const_iterator and read access.
good_actions(size_t idx, int val) {
va_[idx].set(val);
cout << "vector<A> info - " << " size: " << va_.size() << ", max: "
<< va_.max_size() << ", capacity: " << va_.capacity() << ", empty?: "
<< va_.empty() << endl;
if (!va_.empty()) {
cout << "First (old): " << va_[0].get() << ", resetting ..." << endl;
va_[0].set(0);
}
int max = 0;
for (vector<A>::const_iterator i = va_.begin(); i != va_.end(); ++i) {
int n = i->get();
if (n > max) { max = n; }
if (n < 0) { i->set(0); }
}
cout << "Max : " << max << "." << endl;
}
// Everything here should fail at compile.
bad_actions(size_t idx, int val) {
va_[0] = va2_[0];
va_.at(1) = va2_.at(3);
va_.swap(va2_);
va_.erase(va_.begin());
va_.insert(va_.end(), va2_[0]);
va_.resize(1);
va_.clear();
// also: assign, reserve, push, pop, ..
}
};
There is an issue with your requirements. But first let's tackle the fixed size issue, it's called std::tr1::array<class T, size_t N> (if you know the size at compile time).
If you don't know it at compile time, you can still use some proxy class over a vector.
template <class T>
class MyVector
{
public:
explicit MyVector(size_t const n, T const& t = T()): mVector(n,t) {}
// Declare the methods you want here
// and just forward to mVector most of the time ;)
private:
std::vector<T> mVector;
};
However, what is the point of not being assignable if you are mutable ? There is nothing preventing the user to do the heavy work:
class Type
{
public:
int a() const { return a; }
void a(int i) { a = i; }
int b() const { return b; }
void b(int i) { b = i; }
private:
Type& operator=(Type const&);
int a, b;
};
Nothing prevents me from doing:
void assign(Type& lhs, Type const& rhs)
{
lhs.a(rhs.a());
lhs.b(rhs.b());
}
I just want to hit you on the head for complicating my life...
Perhaps could you describe more precisely what you want to do, do you wish to restrict the subset of possible operations on your class (some variables should not be possible to modify, but other could) ?
In this case, you could once again use a Proxy class
class Proxy
{
public:
// WARN: syntax is screwed, but `vector` requires a model
// of the Assignable concept so this operation NEED be defined...
Proxy& operator=(Proxy const& rhs)
{
mType.a = rhs.mType.a;
// mType.b is unchanged
return *this;
}
int a() const { return mType.a(); }
void a(int i) { mType.a(i); }
int b() const { return mType.b(); }
private:
Type mType;
};
There is not much you cannot do with suitable proxies. That's perhaps the most useful pattern I have ever seen.
What you're asking is not really possible.
The only way to prevent something from being assigned is to define the operator = for that type as private. (As an extension of this, since const operator = methods don't make much sense (and are thus uncommon) you can come close to this by only allowing access to const references from your container. But the user can still define a const operator =, and you want mutable objects anyways.)
If you think about it, std::vector::operator [] returns a reference to the value it contains. Using the assignment operator will call operator = for the value. std::vector is completely bypassed here (except for the operator[] call used to get the reference in the first place) so there is no possibility for it (std::vector) to in any way to override the call to the operator = function.
Anything you do to directly access the members of an object in the container is going to have to return a reference to the object, which can then be used to call the object's operator =. So, there is no way a container can prevent objects inside of it from being assigned unless the container implements a proxy for the objects it contains which has a private assignment operator that does nothing and forwards other calls to the "real" object, but does not allow direct access to the real object (though if it made sense to do so, you could return copies of the real object).
Could you create a class which holds a reference to your object, but its constructors are only accessible to its std::vector's friend?
e.g.:
template<typename T>
class MyRef {
firend class std::vector< MyRef<T> >
public:
T& operator->();
[...etc...]
You can achieve what you want by making the std::vector const, and the vector's struct or class data mutable. Your set method would have to be const. Here's an example that works as expected with g++:
#include <vector>
class foo
{
public:
foo () : n_ () {}
void set(int n) const { n_ = n; }
private:
mutable int n_;
};
int main()
{
std::vector<foo> const a(3); // Notice the "const".
std::vector<foo> b(1);
// Executes!
a[0].set(1);
// Failes to compile!
a.swap(b);
}
That way you can't alter the vector in any way but you can modify the mutable data members of the objects held by the vector. Here's how this example compiles:
g++ foo.cpp
foo.cpp: In function 'int main()':
foo.cpp:24: error: passing 'const std::vector<foo, std::allocator<foo> >' as 'this' argument of 'void std::vector<_Tp, _Alloc>::swap(std::vector<_Tp, _Alloc>&) [with _Tp = foo, _Alloc = std::allocator<foo>]' discards qualifiers
The one disadvantage I can think of is that you'll have to be more aware of the const-correctness of your code, but that's not necessarily a disadvantage either.
HTH!
EDIT / Clarification: The goal of this approach is not defeat const completely. Rather, the goal is to demonstrate a means of achieving the requirements set forth in the OP's question using standard C++ and the STL. It is not the ideal solution since it exposes a const method that allows alteration of the internal state visible to the user. Certainly that is a problem with this approach.