I have a simple problem but I don't know how to solve it because I have never used functors in C++.
I want to do something like that (it is just an example) :
class MyClass
{
void applyFunction(myFunction); /* WRONG SYNTAX */
double *_x;
unsigned int *_size;
};
void MyClass::applyFunction(myFunction) /* WRONG SYNTAX */
{
for (unsigned int i = 0; i < _size; ++i)
myFunction(_x[i], 10.);
}
class OtherClass
{
void myFunction1(double x, double lim);
void myFunction2(double x, double lim);
std::vector _v;
};
void OtherClass::myFunction1(double x, double lim)
{
_v.clear();
if (x > lim)
_v.push_back(x);
}
void OtherClass::myFunction2(double x, double lim)
{
_v.clear();
if (x < lim)
_v.push_back(x);
}
int main()
{
MyClass myClass;
OtherClass otherClass;
myClass.applyFunction(otherClass.myFunction1); /* WRONG SYNTAX */
std::cout<<otherClass._v.size()<<std::endl;
myClass.applyFunction(otherClass.myFunction2); /* WRONG SYNTAX */
std::cout<<otherClass._v.size()<<std::endl;
return 0;
}
What would be the correct syntax to use functors/std::functions ?
Thank you very much !
I'll take you at your word that you want to use functors for this. Just for grins, I'll also assume you want to do this the "right" way, not just find a syntax that will let it compile (and probably run, perhaps doing what you wanted).
In this case, the standard library already has algorithms to support much of what you're doing (especially in C++11). To copy the data that meets some criteria into a target vector, you have std::copy_if (though that's missing in C++98/03 -- you have to reverse the sense of the comparison and use std::remove_copy_if).
Using this, your code becomes something like this:
template <class T>
class less_than {
T limit;
public:
less_than(T lim) : limit(lim) {}
bool operator()(T const &val) { return val < limit; }
};
std::copy_if(source.begin(),
source.end(),
std::back_inserter(target),
less_than<int>(10));
However, if you have C++11 available, it's probably more convenient to use a lambda instead:
std::copy_if(source.begin(),
source.end(),
std::inserter(target),
[](int v) { return v < 10;});
The lambda is basically just a way of getting the compiler to generate an anonymous functor class for you, so there's not much real difference between the two, but the lambda obviously saves quite a bit of typing.
If you're stuck with C++03, you basically just invert the comparison:
template <class T>
class greater_than {
T limit;
public:
bool operator()(T const &val) {
return val > limit;
}
};
std::remove_copy_if(src.begin(),
src.end(),
std::back_inserter(dst),
greater_than(10));
Alternatively, you could write your own copy_if pretty easily -- it was left out of C++98/03 mostly by oversight, not because it needs anything the language doesn't provide, or anything like that (though as I recall, getting all the border conditions exactly right can be a little tricky).
For what it's worth, I should also note that the standard library does have std::less and std::greater, so the less_than and greater_than functors I've given above aren't really necessary. Unfortunately, they just do the comparison, so to use them as we're doing here, you have to use std::bind1st or std::bind2nd to get them to compare to a constant:
std::remove_copy_if(src.begin(),
src.end(),
std::ostream_iterator<int>(std::cout, "\n"),
std::bind1st(std::less<int>(), 10));
void applyFunction(std::function<void(double, double)>);
// ...
applyFunction(std::bind(&OtherClass::myFunction1, &otherClass));
Related
In my homework my task is to create the FooCl class for these:
double d[] = {1.3, 0.7, 2.4, 1.5, 6.2, 5.7, 8.6, 9.1};
FooCl<double> itemsD(d, sizeof(d) / sizeof(d[0]));
std::string s[] = {"C++", "Haskell", "Python", "Java"};
FooCl<std::string> itemsS(s, sizeof(s) / sizeof(s[0]));
itemsD.mySort();
itemsS.mySort();
I made a constructor/destructor for it, but I don't know how to create two different functions with templates for the two different types of lists.
I think I would need to use some kind of overloading but don't know how.
template <typename T>
class FooCl
{
private:
T *mItems;
int mItemsSize;
public:
FooCl(T items[], int itemsSize)
{
mItems = new T[itemsSize];
for (int i=0; i<itemsSize; ++i)
{
this->mItems[i] = items[i];
}
this->mItemsSize = itemsSize;
};
~FooCl()
{
delete[] mItems;
}
void mySort()
{
//I have no idea how to write this function, so it can sort two different types of lists.
}
};
If you want to sort any container like std::array or std::vector
template <typename Container, typename Func>
void sort(Container& c, Func functor)
{
std::sort(std::begin(c), std::end(c), functor);
}
usage
std::vector<int> vct {1,2,3,1,2};
sort(vct, [](const int lhs, const int rhs) {return lhs > rhs;});
One way is to use std::sort as shown below:
void mySort()
{
//--vvvvvvvvv------------------------------------>use std::sort
std::sort(mItems, mItems + mItemsSize);
}
You can even write your sort functionality/implementation which will include the use of mItems and mItemsSize.
The two operations important for sorting is comparison and swapping.
Both double and std::string already have definitions for <, which is the idiomatic comparison operator.
There is already a template std::swap, which is the idiomatic swap function.
You need to write a sort that uses mItems and mItemsSize, comparing items (with <) and swapping those that are in the wrong position (with std::swap).
I am programming in C++ (still a beginner), and I was wondering a question about generating automatically value members of class into string for example :
class Point
{
private:
int x;
int y;
public:
std::list<std::string> getValues();
}
In my opinion, I think I must code the function getValues, transform the ints into strings and put the string in a list and return the list, but my tutor asks me if there is a way to do this function automatically,without writting the code, and I don't know how to answer.
Because if we add a new member value (ex : int z), we will have to recode the function getValues().Apparently there is some way to do this in Java,but I was wondering if there is similar way into C++.
Best regards
It is difficult to say what your tutor really wanted from you, but if I were your tutor I would love you to learn about Boost.Fusion Adapted Structures and techniques it is based on (in particular typemaps).
Example with Boost.Fusion:
#include <boost/fusion/adapted/struct/define_struct.hpp>
#include <boost/fusion/algorithm/iteration/fold.hpp>
#include <boost/lexical_cast.hpp>
#include <iterator>
#include <list>
#include <string>
#include <iostream>
BOOST_FUSION_DEFINE_STRUCT(
(), Point,
(int, x)
(long, y)
(double, z)
)
template <class Itr> struct collector_t
{
using result_type = Itr;
template <class T>
Itr operator()(Itr itr, T const& val) const { *itr = boost::lexical_cast<std::string>(val); return ++itr; }
};
int main()
{
Point p {123, 456l, 123.456};
// create and populate the resulting list using boost.fusion facilities
std::list<std::string> strings;
auto sink = std::back_inserter(strings);
boost::fusion::fold(p, sink, collector_t<decltype(sink)>());
// dump the resulting list to prove the example
for (auto s: strings) std::cout << s << '\n';
return 0;
}
There is no way to do this automatically in C++. That would require reflection, i.e., code must be able to reason about the fields a class has. This is not possible in C++. It is possible in Java, so you are right, one can do this automatically in Java.
In a non-automated way: using visitation (compile-time).
class Point {
public:
//
// With visitation (names are optional)
//
template <typename Visitor>
void visit(Visitor&& visitor) {
visitor("x", x);
visitor("y", y);
}
template <typename Visitor>
void visit(Visitor&& visitor) const {
visitor("x", x);
visitor("y", y);
}
//
// With tuples
//
auto as_tuple() -> std::tuple<int&, int&> {
return std::tie(x, y);
}
auto as_tuple() const -> std::tuple<int const&, int const&> {
return std::tie(x, y);
}
private:
int x;
int y;
};
Yes, those solutions require some more maintenance. However all the code is exposed without the need to mentally expand a macro. As a result, potential compilation error messages tend to be clearer and understanding is eased.
As for the maintenance burden ?
you can automate (unit-test) the correlation of the two methods (make sure they both return the same number of members in the same order)
automating detection of incomplete methods is slightly harder, but if a member is missing and tested it will show up too
Note: I personally prefer the as_tuple version, it makes writing == and < so easy.
Note: detection of incomplete methods (missing members) can be attempted using sizeof and the ABI rules.
The question really has two parts:
Finding all members and
Converting them to string.
Finding members is not possible in pure C++, because it does not have any form of reflection. You could resort to special declaration macros using the standard preprocessor like Boost.Fusion does or you can use your own preprocessor like OpenC++ or using the Clang front-end.
For converting to strings, the standard approach would then be like this:
template <typename T>
std::string to_string(T const &v) {
std::stringstream s;
s << v;
return s.str();
}
You can avoid typing this in and use Boost.Lexical Cast.
Note that C++11 also has std::to_string, but it is only defined for numeric types and therefore not very useful for this purpose.
I've been playing around a lot with the new C++11 lambda's, and the requirement to fully specify the template argument is a real drag. The syntax I would like to be using is something similar to the following:
#include <vector>
#include <algorithm>
struct foo
{
void bar() {}
};
int main()
{
vector<foo> v(10);
for_each(v.begin(), v.end(), [](f) {f.bar();});
^^^
}
Is there any way to get anything approximately close to this? Boost's Phoenix library is OK, but the syntax for calling member functions requires lots of boiler plate - I guess I'm after C++11's ease of calling member functions coupled with Phoenix's automatic deduction of type.
Current idea
I have gotten it down to this syntax:
vector<foo> x(1);
vector<bar> y(1);
for_each(x.begin(), x.end(), [](_a f) {f->f();});
for_each(y.begin(), y.end(), [](_a b) {b->b();});
Which works, but you have to add the capability per type (eg. ADD_AUTO_LAMBDA_SUPPORT(foo);). It also has the limitation that all supported types can not have any ambiguous members.
The full code for that is:
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
struct foo
{
foo() : x(3) {}
int x;
void f() { cout << x << endl;}
};
struct bar
{
bar() : y(133.7) {}
double y;
void b() { cout << y << endl;}
};
struct combo : foo, bar { };
struct _a
{
_a(foo& f) : offset(reinterpret_cast<combo*>(&f)) {}
_a(bar& b) : offset(reinterpret_cast<combo*>((char*)&b - 2*sizeof(foo))) {}
combo* operator->() { return offset; }
private:
combo* offset;
};
int main()
{
vector<foo> x(1);
vector<bar> y(1);
for_each(x.begin(), x.end(), [](_a f) {f->f();});
for_each(y.begin(), y.end(), [](_a b) {b->b();});
}
You could then use some template and preprocessor magic to generate both _a and combo, but the issue comes when you have ambiguous names (eg. a third struct with a b() function - you need a way to disambiguate them that I can't think of at the moment.
Note: I fully agree that [](auto f){ ... } would be very desirable!
While we don't have that, what about good old typedef? It just adds one line, is very "low-tech" and makes the lambda easy to read:
typedef const map<key_type, value_type>::value_type& λp_t;
for_each(m.begin(), m.end(), [&](λp_t x) {...});
You can use decltype:
for_each(m.begin(), m.end(), [&](decltype(*m.begin()) x){...});
But it really, really sucks that you cant use auto in anonymous lambdas.
Update:
You could also do
#define _A(CONTAINER_NAME) decltype(*CONTAINER_NAME.begin())
for_each(m.begin(), m.end(), [&](_A(m) x) { ... });
So, presumably in the case of the following:
std::array<int,10> a;
for_each(begin(a),end(a),[](auto i){ /* ... */ });
You want the compiler to figure out that the lambda takes an int and basically read this as:
for_each(begin(a),end(a),[](int i){ /* ... */ });
The issue is that the type of the lambda affects the type of the for_each template instantiation, which might choose a different specialization, which could in turn require a different type deduction for the lambda parameter. So there is simply no reasonable way for the compiler to use the algorithm code to automatically deduce the type of the arguments you pass in.
Anyway, at least for the for_each algorithm you don't need this, just use the range for loop:
for(auto i:a) { /* ... */ }
And in other places use decltype:
transform(begin(a),end(a),begin(a),[](decltype(*begin(a)) i) { return 2*i; });
You can have lambda deduce it parameters(and types) from the function, but then each function has to make that available. This discusses how that could be accomplished here:
http://groups.google.com/group/comp.lang.c++.moderated/browse_thread/thread/c347334187628476?hl=en
Basically you can call functions using a ruby-like way. So you would call for_each like this:
$(for_each(some_range), x)
{
printf("%i\n", x);
};
The ($) dollar sign is a macro that takes care of deducing the type from the function. Now this won't work with std::for_each, it has to be used with a specially defined function that emits the parameter types for the lambda.
Since it uses a macro it doesn't take into account operator precedence, so you can't use it with range adapters.
If you're willing to use macros and use all that setup wouldn't a shortcut macro using decltype be sufficient? Something like:
#define T_FOR_EACH( begin_, end_, var_, func_ ) \
for_each( (begin_), (end_), [](decltype(*begin_) var_) func_ )
Then you could have:
T_FOR_EACH(x.begin(), x.end(), &f, {f->f();} );
The reason I don't put & for the variable in the define is that with this format would can still specify all the type specifiers you want and whether it is a reference or copy.
Excuse me if the syntax is wrong, I don't have a C++11 compiler around I can test any of this with, it's just an idea.
So this compiles
#define FOR_EACH_IN(iter__, list__, ...) \
std::for_each(list__.begin(), list__.end(), [&](decltype(*list__.begin()) iter__) __VA_ARGS__)
Given:
auto DoSomethingTo = [](T AnElement){ /* insert profitable activity */ };
std::array<T, n> AnArray;
You can do:
FOR_EACH_IN(AnElement, AnArray,
{
DoSomethingTo(AnElement);
});
The JavaScript fanboy inside me is excited by how it looks but as a C++ coder I'm horrified to have come up with something like this. It's likely to trip lots of static analyses and linters, plus when something goes wrong I hope you enjoy debugging macros.
But, hey, it's clean.
Can you use templates (or the like) in C++ to specify which operation is done in a function?
I don't know how to explain it more clearly, so I'll show you how it could be (but isn't) done in code:
template <operator OPERATION> int getMaxOrMin(int a, int b) {
return a OPERATION b ? a : b;
}
where finding the maximum or the minimum of a or b would be (this is where my pseudo-syntax gets a little confusing, bear with me):
int max = getMaxOrMin< > > (a, b);
int min = getMaxOrMin< < > (a, b);
I know that's not how to do it at all (because it doesn't even syntactically make sense), but I hope that clarifies the type of thing I want to do.
The reason behind me wondering this is I'm making a PriorityQueue implementation, and it would be nice to easily switch between the backing being a max-heap or a min-heap on the fly without copying and pasting code to make two different classes.
I know I could do it with a macro, but the only way I'd know how to do that would give me either a max-heap or a min-heap, but not both in the same compilation. I'm probably overlooking a way, though.
Do what std::map and friends do: Take a comparison function/functor as your template parameter. See std::less and std::greater.
Do remember that the standard library already has a well developed and debugged priority queue that you can use with an arbitrary comparison function.
Yes but you need to define it like a functor:
template <typename OPERATION>
int getMaxOrMin(int a, int b)
{
OPERATION operation;
return operation(a, b) ? a : b;
}
Now you can use it like this:
struct myLess
{
bool operator()(int a,int b) const { return a < b; }
}
struct myGreat
{
bool operator()(int a,int b) const { return a > b; }
}
void code()
{
int x = getMaxOrMin<myLess>(5,6);
int y = getMaxOrMin<myGreat>(5,6);
}
That seems like a lot of work. But there are a lot of predefined functors in the standard. On this page scroll down to "6: Function Objects".
For your situation there is:
std::less
std::greater
So the code becomes:
template <typename OPERATION>
int getMaxOrMin(int a, int b)
{
OPERATION operation;
return operation(a, b) ? a : b;
}
void codeTry2()
{
int x = getMaxOrMin<std::less<int> >(5,6);
int y = getMaxOrMin<std::greater<int> >(5,6);
}
I recently discovered that in C++ you can overload the "function call" operator, in a strange way in which you have to write two pair of parenthesis to do so:
class A {
int n;
public:
void operator ()() const;
};
And then use it this way:
A a;
a();
When is this useful?
This can be used to create "functors", objects that act like functions:
class Multiplier {
public:
Multiplier(int m): multiplier(m) {}
int operator()(int x) { return multiplier * x; }
private:
int multiplier;
};
Multiplier m(5);
cout << m(4) << endl;
The above prints 20. The Wikipedia article linked above gives more substantial examples.
There's little more than a syntactic gain in using operator() until you start using templates. But when using templates you can treat real functions and functors (classes acting as functions) the same way.
class scaled_sine
{
explicit scaled_sine( float _m ) : m(_m) {}
float operator()(float x) const { return sin(m*x); }
float m;
};
template<typename T>
float evaluate_at( float x, const T& fn )
{
return fn(x);
}
evaluate_at( 1.0, cos );
evaluate_at( 1.0, scaled_sine(3.0) );
A algorithm implemented using a template doesn't care whether the thing being called is a function or a functor, it cares about the syntax. Either standard ones (e.g. for_each()) or your own. And functors can have state, and do all kinds of things when they are called. Functions can only have state with a static local variable, or global variables.
If you're making a class that encapsulates a function pointer, this might make the usage more obvious.
The compiler can also inline the functor and the function call. It cannot inline a function pointer, however. This way, using the function call operator can significantly improve performance when it is used for example with the standard C++ libary algorithms.
For example for implementing generators:
// generator
struct Generator {
int c = 0;
virtual int operator()() {
return c++;
}
};
int sum(int n) {
Generator g;
int res = 0;
for( int i = 0; i < n; i++ ) {
res += g();
}
return res;
}
I see potential to yet one exotic use:
Suppose you have object of unknown type and have to declare another variable of same type, like this:
auto c=decltype(a*b)(123);
When such pattern used extensively, decltype become very annoying.
This case can occur when using some smart type system that automatically invent type of result of functions and operators based on types of arguments.
Now, if each specialization of each type of that type system equipped with
magic definition of operator() like this:
template<????> class Num<???>{
//specific implementation here
constexpr auto operator()(auto...p){return Num(p...);}
}
decltype() no more needed, you can write simply:
auto c=(a*b)(123);
Because operator() of object redirects to constructor of its own type.