I am trying to get a bit of practice with std::transform by using it to decrypt a simple Caesar cypher. But apparentrly my function definition is wrong, since the compiler considers the unary function argument invalid. Here is my code:
char CryptoModule::UndoCaesar(char& letter)
{
return (letter - atoi(key_.c_str()) % 128);
}
void CryptoModule::DecryptCaesar()
{
std::transform(data_.begin(), data_.end(), data_.begin(), UndoCaesar);
}
Could anyone please tell me where the error lies ? In addition, what would I need to modify in order to use for_each ? I believe it would involve changing the return value to a void and storing the result in letter.
Thanks and have a nice day
Edit: Tried adding bind, but still not working. Current call is :
std::transform(data_.begin(), data_.end(), data_.begin(), bind(&UndoCaesar, this, std::placeholders::_1));
Your given member function has a hidden this parameter, so you need to bind that in order to pass it:
std::transform(data_.begin(), data_.end(), data_.begin(),
std::bind(&CryptoModule::UndoCaesar, this, std::placeholders::_1)
);
Note that std::bind is in <functional>. All this does is basically cause std::transform to call whatever function-like object, f, it takes like f(currentElement) and have that in turn call UndoCaesar(this, currentElement) with this being part of its state because you bound it.
Alternatively, you can wrap the call in a lambda that captures this so that it can be used for the member function call (implicitly, like normal):
std::transform(data_.begin(), data_.end(), data_.begin(),
[this](char c) {return UndoCaesar(c);}
);
Related
I have the following code:
void MyClass::create_msg(MyTime timestamp) {
// do things here ...
}
and I tried to create a std::bind for the above function:
MyMsg MyClass::getResult(MyTime timestamp) {
// do things here ...
std::bind(create_msg(), timestamp);
// do things ...
}
But got the following error:
error: too few arguments to function call, single argument 'timestamp' was not specified
std::bind(create_msg(), timestamp);
~~~~~~~~~~ ^
MyClass.cpp:381:1: note: 'create_msg' declared here
void MyClass::create_msg(MyTime timestamp) {
^
1 error generated.
What did I do wrong in this case? Thanks!
By the way, same error if I do:
std::bind(&MyClass::create_msg(), this, timestamp);
There are three issues here.
First, the argument you're giving to std::bind as your function is currently create_msg(). This means "call create_msg, take whatever result it produces, and pass that in as the first argument to std::bind." That's not what you want - you instead meant "take create_msg and pass it as the first parameter to std::bind." Since create_msg is a member function, you'll need to get a pointer to it like this:
std::bind(&MyClass::create_msg, /* ... */)
That will address one issue, but there's another one that will then pop up. When you use std::bind with a member function pointer, you need to prove std::bind with an extra parameter corresponding to the receiver object to use when calling that member function. I believe that in your case you want the current object to be the receiver, which would look like this:
std::bind(&MyClass::create_msg, this, timestamp)
That should work properly.
However, one could argue that there's a third issue here - rather than using std::bind, why not just use a lambda expression?
[timestamp, this] { create_msg(timestamp); }
So I wanted to challenge myself by writing a small threadpool in C++, and I wanted to try to mimic the easy to use way that std::thread work with, that you can just create a thread and as parameters send a function and parameters for that function, compared to something like pthreads which force you to have a void* as the only indata for the function.
So far I have been able to use templates and parameter packs to create a function that can take another function and parameters for it and execute it, but I can't find a way to store them so that I can execute them at a later time (when there is a free thread in the threadpool). I have tried using both std::function together with std::tuple, and std::bind, but since I don't know exactly what types I am dealing with I can't find a way to store the function and the parameters so that I can use them later on in another part of my code, since at that point I no longer know what types everything is of. Down below is some code I have been messing around with that might help show how I mean.
template<typename Function, typename... Arguments>
void TestFunction(Function func, Arguments... parameters)
{
std::function<std::result_of<Function(Arguments...)>::type(Arguments...)>* tempFunc;
tempFunc = new std::function<std::result_of<Function(Arguments...)>::type(Arguments...)>(func);
void* funcPtr = tempFunc;
std::tuple<Arguments...>* tempTuple;
tempTuple = new std::tuple<Arguments...>(parameters...);
void* tuplePtr = tempTuple;
//func(parameters...);
(Arguments...)>*)funcPtr, *(std::tuple<Arguments...>*)tuplePtr);
auto bindTest = std::bind(func, parameters...);
bindTest();
void* bindPtr = &bindTest;
}
int main()
{
TestFunction(std::printf, "%d, %d, %d\n", 3, 2, 1);
getchar();
return 0;
}
It might be that it's not possible to do what I want to do, and in that case I guess I'll just have to switch to an approach more like pthreads. But if anyone knows a work around I would be grateful.
The key thing is that you can store the return type of std::bind in a std::function. Because std::bind returns an object that is callable. You should then be able to store the std::function instance depending on how you want to handle the return type.
template<typename Function, typename... Arguments>
void TestFunction(Function func, Arguments... parameters)
{
using Ret = typename std::result_of<Function>::type;
std::function<Ret()> val{std::bind(func, parameters...)};
}
If you do this when you first recive the function you no longer have to think about the arguments type, and only the return type. How you handle the return type will depend on the usecase of storing the function. One simple approach is to require that Function is a void function, which may make sense if there is no way to pass the value back to the consumer of the API.
I want to replace some older code with simpler, functor based code. But I don't want to introduce a functor class for this and use boost::lambda/phoenix for this as I don't have C++11 at hand.
Old code looks like this
int player = ...;
Point middlePt = ...;
for(Point pt=<magic with nested loops>)
if(this->IsMilitaryBuilding(pt) && (this->GetNode(pt).owner == player + 1))
return true;
return false;
I have a function that calls Functor for every point (encapsulating the magic) and returns true when any of those calls returns true:
template<class Functor>
bool CheckPts(Point middlePt, Functor f);
Translating this for the first part of the if is easy:
return CheckPts(middlePt, bind(&IsMilitaryBuilding, this, _1));
And for the 2nd I'd want to do something like: bind(&GetNode, this, _1).owner == player+1 which is not supported.
What is the most readable way of doing this? I think this might be solvable by binding a reference to this and calling the functions directly using phoenix lambda but I did not found any references that go beyond simple 'Hello World' lambdas accessing only a simple member or a parameter.
After using all_of succesfully once I tried to do it again.
if (all_of(Enemies.begin(), Enemies.end(), in_lock_range))
{
lock_on = -1;
}
The vector is:
std::vector<Enemy> Enemies;
The function is:
bool Player::in_lock_range(Enemy arg)
{
if (get_distance(mouseTarget.x, mouseTarget.y, arg.x, arg.y) > arg.erect.r) return true;
else return false;
}
get_distance(x1,x2,y1,y2) returns the distance from 2 points
Enemy is a friend class to Player and vice versa so they use each other's stuff freely.
The error I recieve is
error C3867: 'Player::in_lock_range': function call missing argument list; use '&Player::in_lock_range' to create a pointer to member
I'm not sure why he is apparently asing for agruments for in_lock_range when I don't believe it needs any when in all_of, as I have used it in a different situation with no such issue.
Can anyone please explain to me what the cause of this can be? I am not really experienced in this. Thanks.
It's a member function, so the syntax for taking a pointer is
&Player::in_lock_range
This is only usable if it's a static member, since it must be callable with just a single argument. I'm guessing it isn't - presumably mouseTarget is a non-static data member of Player. In that case, you'll have to bind it to some player object:
bind(&Player::in_lock_range, std::ref(some_player), std::placeholders::_1)
or wrap it in a lambda:
[&](const Enemy& e){return some_player.in_lock_range(e);}
The function should probably take its argument by constant reference rather than value; and you might want to simplify the return statements
if (whatever) return true;
else return false;
to the more readable
return whatever;
I was thinking about doing a take_timing function that would take the timing of any function passed to it. By any function it means that the arguments this callback takes is unknown by the caller. It would take too the arguments for the callback. But as it doesn't know how to call it, it would take another callback function, the caller of the callback, written by the function user. The stub would be something like this:
void take_timing(
void (*callback)(),
void (*caller(void (*callback)(),void* args_struct),
void* args_struct
)
{
// Start timer
caller(callback,args_struct);
// Stop timer, read timings, record...
}
void some_caller(void (*callback)(),void* args_struct)
{
// Cast "callback" to function signature
// Cast args_struct to some struct with args
// Call the callback with correct args signature
}
So comes my questions:
Is it possible?
Can it use variable arguments list to make it simples? How? I am helpless on this...
Is there a better way of doing it? Or is it just better to do a take_timing for every specific case?
Is there a OOP Design Pattern for this for use with C++?
I myself gave up on this, but put it here out of curiosity, maybe some very useful insights.
Just take a functor as a template argument. Something like:
template<typename F>
nanoseconds take_timing(F f) {
auto start = high_resolution_clock::now();
f();
auto end = high_resolution_clock::now();
return end - start;
}
long long factorial(int i);
take_timing( [](){factorial(20);} ); // wrap call to function taking arguments in zero-argument lambda
You're looking for varargs support, which does exist in ANSI C. A gazillion or so google hits will result if you search for it. Here's one at random: http://www.eskimo.com/~scs/cclass/int/sx11b.html
One way to handle this is to take a boost::bind function object as your parameter:
http://www.boost.org/doc/libs/1_48_0/libs/bind/bind.html
You could hide the fact that closures are involved with macros.