Passing variables between functions doesnt work - c++11

Im new to c++ and right now going through a course.
Im coding a bulls and cows guess my word game.
I finished the code, but it didnt work the way i wanted.
It fails when i try to pass variables between two functions.
thats the code:
#include <iostream>
#include <string>
using namespace std;
void PrintIntro(); <-- the function that passes the variable
void PlayGame(); <-- the function trying to get the vriable
string PlayersGuess();
int main()
{
// Printing the Intro and Instrations of the game
PrintIntro();
// Function to play our game
PlayGame();
return 0; // exits the application
}
void PrintIntro()
{
// introduce the game
constexpr int WORD_LENGTH = 5;
cout << "Welcome to Bulls and Cows" << endl;
cout << "Can you guess the " << WORD_LENGTH << " letter word I'm thinking of?" << endl;
cout << endl;
PlayGame(WORD_LENGTH); <-- Taking the variable
return;
}
string PlayersGuess()
{
// get a guess from the player
cout << "Enter your guess: ";
string Guess = "";
getline(cin, Guess);
cout << endl;
return Guess;
}
void PlayGame(const int &passed) <-- passing through here
{
// Game Intro
for (int i = 0; i < passed; i++) <-- to here
{
// Players Guess
string Guess = PlayersGuess();
cout << "Your guess is: " << PlayersGuess() << endl;
cout << endl;
}
}
The result is a fail and it says "Function does not take 1 argument"
What is the right way to pass it?

Change the declaration :
void PlayGame()
To:
void PlayGame(const int &passed)

The declaration void PlayGame(); in the beginning does not accept parameter. Change the declaration to accept parameter of the required type. Declaration and definition must match. Hope this helps.

If you want a function to take an argument, you have to tell the compiler it takes an argument.
The function prototype declaration
void PlayGame();
tells the compiler that the PlayGame function takes no arguments, and return no value. If you then try to call it using an argument that doesn't match the declaration and you will get an error.
On the other hand, if you declare it like your definition:
void PlayGame(const int &passed);
then you tell the compiler that the function must take an argument (a reference to a constant int), and you can not call the function without argument.
If you want different behavior depending on the argument (or lack thereof) passed, then you have two solutions: Function overloading, or default arguments.
For example, you can have two different functions with the same name, but different signature (basically different arguments), so you can have e.g.
void PlayGame() { ... }
void PlayGame(int passed) { ... }
Then (with the right forward declarations) you can call it with either no arguments in which case the first function will be called, or with an integer value in which case the second function will be called.
Using default arguments you can do something like
void PlayGame(int passed = 0) { ... }
Then if you call the function with an argument that argument will be passed, if you pass it without any argument the default value (0 in my example) will be used.
Also note that I removed the constant reference part, that's not really needed for simple int values.
All of this should be clearly explained in any good book.

Signatures of functions' declaration and definition must match each other. You need to declare functions like this:
void PlayGame(const int &passed);
In your code you have two different functions with name PlayGame. In the moment when PlayGame() is called with a parameter a compiler hasn't met the appropriate function yet so it gives the error.

Related

Boost asio post with shared ptr passed as argument with std::move

I am new to boost:asio. I need to pass shared_ptr as argument to handler function.
E.g.
boost::asio::post(std::bind(&::function_x, std::move(some_shared_ptr)));
Is using std::move(some_shared_ptr) correct? or should I use as below,
boost::asio::post(std::bind(&::function_x, some_shared_ptr));
If both are correct, which one is advisable?
Thanks in advance
Regards
Shankar
Bind stores arguments by value.
So both are correct and probably equivalent. Moving the argument into the bind is potentially more efficient if some_argument is not gonna be used after the bind.
Warning: Advanced Use Cases
(just skip this if you want)
Not what you asked: what if function_x took rvalue-reference arguments?
Glad you asked. You can't. However, you can still receive by lvalue reference and just move from that. because:
std::move doesn't move
The rvalue-reference is only there to indicate potentially-moved-from arguments enabling some smart compiler optimizations and diagnostics.
So, as long as you know your bound function is only executed once (!!) then it's safe to move from lvalue parameters.
In the case of shared-pointers there's actually a little bit more leeway, because moving from the shared-ptr doesn't actually move the pointed-to element at all.
So, a little exercise demonstrating it all:
Live On Coliru
#include <boost/asio.hpp>
#include <memory>
#include <iostream>
static void foo(std::shared_ptr<int>& move_me) {
if (!move_me) {
std::cout << "already moved!\n";
} else {
std::cout << "argument: " << *std::move(move_me) << "\n";
move_me.reset();
}
}
int main() {
std::shared_ptr<int> arg = std::make_shared<int>(42);
std::weak_ptr<int> observer = std::weak_ptr(arg);
assert(observer.use_count() == 1);
auto f = std::bind(foo, std::move(arg));
assert(!arg); // moved
assert(observer.use_count() == 1); // so still 1 usage
{
boost::asio::io_context ctx;
post(ctx, f);
ctx.run();
}
assert(observer.use_count() == 1); // so still 1 usage
f(); // still has the shared arg
// but now the last copy was moved from, so it's gone
assert(observer.use_count() == 0); //
f(); // already moved!
}
Prints
argument: 42
argument: 42
already moved!
Why Bother?
Why would you care about the above? Well, since in Asio you have a lot of handlers that are guaranteed to execute precisely ONCE, you can sometimes avoid the overhead of shared pointers (the synchronization, the allocation of the control block, the type erasure of the deleter).
That is, you can use move-only handlers using std::unique_ptr<>:
Live On Coliru
#include <boost/asio.hpp>
#include <memory>
#include <iostream>
static void foo(std::unique_ptr<int>& move_me) {
if (!move_me) {
std::cout << "already moved!\n";
} else {
std::cout << "argument: " << *std::move(move_me) << "\n";
move_me.reset();
}
}
int main() {
auto arg = std::make_unique<int>(42);
auto f = std::bind(foo, std::move(arg)); // this handler is now move-only
assert(!arg); // moved
{
boost::asio::io_context ctx;
post(
ctx,
std::move(f)); // move-only, so move the entire bind (including arg)
ctx.run();
}
f(); // already executed
}
Prints
argument: 42
already moved!
This is going to help a lot in code that uses a lot of composed operations: you can now bind the state of the operation into the handler with zero overhead, even if it's bigger and dynamically allocated.

virtual method callbacks in C++11/14/17?

I have some subscription function that will call my callback when something happens. (Let's say it's a timer, and will pass me an object when a certain number of milliseconds elapses.) The thing I want to be called is a virtual method. I feel std::function and std::bind or lambdas are part of the solution.
The C++99 approach I've used until now involves one-line C functions that know how to call a virtual method. The subscription function takes the C function and a void* user data as arguments. For example:
class Foo {
virtual void OnTimerA( Data* pd );
};
void OnTimerACB( Data* pd, void* pvUserData ) {
( (Foo*) pvUserData )->OnTimerA( pd );
}
/* Inside some method of Foo; 1000 is a number of milliseconds to call me back in;
second arg is a function pointer; third is a void* user data that is passed back
to the C callback. */
SubscribeToTimerOld( 1000, OnTimerACB, this );
What I'm hoping for is a way to write:
SubscribeToTimerNew( 1000, OnTimerA );
or something similar, at least that disposes of the need to write that one-line C binding callback.
I have a feeling that SubscribeToTimerNew()'s argument is probably a std:function of some sort and instead of merely writing OnTimerA I'd have to write something with std::bind to get the this pointer in there.
Alternatively to bind, perhaps a lambda is the way to do it? This compiles, though I dont see how to extend it to let the event handler pass an argument to OnTimerA(). (My linker isn't currently working so don't know if it links or runs as desired.)
SubscribeTimer( 1000, [this](){this->OnTimerA();} );
To mention one alternative I've discarded: give Foo a superclass with a method called OnTimer() that will be called when the timer goes off. Now SubscribeTimer() only need take an elapsed time. I don't like this as it doesn't cleanly allow for multiple timers to be registered. If it did you could give them (say) integer timer ID's and implement OnTimer() as a switch but this seems to be a lot more complicated than the C++99 solution.
Ultimately of the (I assume) several approaches, are there any trade-offs (e.g., heap use) in addition the most obvious question of how much typing is involved? (This is a high-performance application and I'd prefer to minimize or eliminate heap usage.)
C++11, C++14 and C++17 are quite different, especially when it comes to lambdas. And lambdas are a great way to create callbacks. For instance, see Why use std::bind over lambdas in C++14?
Using modern C++, you can use std::function as your callback type and then you can use any callable stuff as an actual callback. Quote from https://en.cppreference.com/w/cpp/utility/functional/function:
Class template std::function is a general-purpose polymorphic function
wrapper. Instances of std::function can store, copy, and invoke any
Callable target -- functions, lambda expressions, bind expressions, or
other function objects, as well as pointers to member functions and
pointers to data members.
Example:
#include <functional>
#include <iostream>
using Callback = std::function<void(int)>;
void subscribe(Callback callback, int duration) {
callback(duration);
}
struct Foo {
void operator()(int duration) {
std::cout << __PRETTY_FUNCTION__ << ' ' << duration << '\n';
}
};
struct Bar {
virtual void myFunction(int duration) {
std::cout << __PRETTY_FUNCTION__ << ' ' << duration << '\n';
}
};
void freeFunction(int duration) {
std::cout << __PRETTY_FUNCTION__ << ' ' << duration << '\n';
}
struct Zorg {
static void staticFunction(int duration) {
std::cout << __PRETTY_FUNCTION__ << ' ' << duration << '\n';
}
};
int main() {
Foo foo;
subscribe(foo, 128);
Bar bar;
auto lambda = [&bar](int duration) {
bar.myFunction(duration);
};
subscribe(lambda, 256);
subscribe(freeFunction, 512);
subscribe(Zorg::staticFunction, 1024);
}
Output:
void Foo::operator()(int) 128
virtual void Bar::myFunction(int) 256
void freeFunction(int) 512
static void Zorg::staticFunction(int) 1024

C++ why overloading (T&) in template with (T*)

in C++, if a method is accepting left reference + pointer only,
it seems it suffices if we only have a template method with T& as its parameter, why we usually overload with test(T* ) as well ?
proof of concept: left reference method can take pointer argument.
#include <iostream>
using namespace std;
template<class T>
void test(T& arg) {
T value = arg;
cout << *value << endl;
}
int main() {
int b = 4;
int* a = &b;
test(a); // compiles and runs without issue.
return 0;
}
Why [do] we usually overload with test(T* ) as well?
I am not sure that we usually do anything of the sort, but if one were to overload for a pointer, it would be because pointers behave differently than object types. Remember, a pointer in fact is not an object but an address to an object.
The reason that test(a) compiles and runs without issue is because it is accepting a reference to a pointer to an object as its parameter. Thus, when the line cout << *value << endl; executes, the pointer is dereferenced back to an object and we see 4 printed to standard out.
As #HolyBlackCat mentioned, we usually want do different things for T& and T*.
As indicated in the example, for test(T&) we usually need to manually do dereference, this would result in the difference in the behavior, so it makes sense to have a overload like this.

What does <int(int)> mean in a function template?

I know this is an easy question but I can't seem to find a specific answer anywhere!
Going through test code for threads in c++11, and don't understand the meaning of this template function statment:
packaged_task<int(int)> task1(&myComputation);
Not sure what 'int(int)' means in this code. I understand in general that what is passed into the brackets < > is the type of what is being passed to the template definition. Is this some sort of type casting?
Thanks!
In this context, the int(int) represents the type signature of a function pointer to a function that takes one parameter (an int), and returns an int. So, if I were to write:
int myFunction(int value) {
std::cout << value << std::endl;
}
std::packaged_task<int(int)> myPackagedTask{&myFunction};
the packaged_task would now contain a function pointer to myFunction. Following, this would be an error:
int mySecondFunction(int value, int secondValue) {
std::cout << value << " : " << secondValue << std::endl;
}
std::packaged_task<int(int)> myPackagedTask{&mySecondFunction}; //compile error, mySecondFunction does not match signature int(int)

std::string::assign vs std::string::operator=

I coded in Borland C++ ages ago, and now I'm trying to understand the "new"(to me) C+11 (I know, we're in 2015, there's a c+14 ... but I'm working on an C++11 project)
Now I have several ways to assign a value to a string.
#include <iostream>
#include <string>
int main ()
{
std::string test1;
std::string test2;
test1 = "Hello World";
test2.assign("Hello again");
std::cout << test1 << std::endl << test2;
return 0;
}
They both work. I learned from http://www.cplusplus.com/reference/string/string/assign/ that there are another ways to use assign . But for simple string assignment, which one is better? I have to fill 100+ structs with 8 std:string each, and I'm looking for the fastest mechanism (I don't care about memory, unless there's a big difference)
Both are equally fast, but = "..." is clearer.
If you really want fast though, use assign and specify the size:
test2.assign("Hello again", sizeof("Hello again") - 1); // don't copy the null terminator!
// or
test2.assign("Hello again", 11);
That way, only one allocation is needed. (You could also .reserve() enough memory beforehand to get the same effect.)
I tried benchmarking both the ways.
static void string_assign_method(benchmark::State& state) {
std::string str;
std::string base="123456789";
// Code inside this loop is measured repeatedly
for (auto _ : state) {
str.assign(base, 9);
}
}
// Register the function as a benchmark
BENCHMARK(string_assign_method);
static void string_assign_operator(benchmark::State& state) {
std::string str;
std::string base="123456789";
// Code before the loop is not measured
for (auto _ : state) {
str = base;
}
}
BENCHMARK(string_assign_operator);
Here is the graphical comparitive solution. It seems like both the methods are equally faster. The assignment operator has better results.
Use string::assign only if a specific position from the base string has to be assigned.

Resources