What does <int(int)> mean in a function template? - c++11

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)

Related

Why does the index of a `char **` type give the whole string?

Consider this snippet:
#include <iostream>
using std::cout;
using std::endl;
int main()
{
char c[] = {'a','b','c','\0'};
char *pc = c;
char **ppc = &pc;
cout << ppc[0] << endl;
}
This prints abc as output. Why does the index of a pointer to pointer to char return the whole string? Here, ppc only points to another pointer that points to a single char. How does it know about the whole string and why would it return it?
You have to understand what std::cout is and why it treats a char* as a "string".
Lets start:
std::cout is an instance of an std::ostream and std::ostream has a lot of operators. What does it mean?
The implementation of std::ostream can, but only as an example here, written like:
class ostream
{
// ... a lot more code for constructors and others
ostream& operator <<( const int );
ostream& operator <<( const double );
ostream& operator <<( char* ); <<< this is the implementation you search for!
// a long list of more special overloads follow
};
And the implementation simply puts out the "string" which the char* points to.
What you see is simply a special overload of the operator<< for the std::ostream class.
OK, the real implementation uses a non-member overload, but that is not important for understanding how std::ostream works in principal.
For more details see: std::ostream::operator<<()
Character and character string arguments (e.g., of type char or const char*) are handled by the non-member overloads of operator<<. Attempting to output a character using the member function call syntax (e.g., std::cout.operator<<('c');) will call one of overloads (2-4) and output the numerical value. Attempting to output a character string using the member function call syntax will call overload (7) and print the pointer value instead.
These are equivalent:
cout << ppc[0] << endl;
cout << *( ppc + 0 ) << endl;
cout << *ppc << endl;
cout << *(&pc) << endl;
cout << pc << endl;

Using tuple as a parameter of a function

Hi I'm trying to pass a tuple as a parameter to a function.
I would like to not to specify the amount of elements in the tuple (I followed this example: tuple as function argument)
What is missing now is how I can count the number of element into the tuple in order to access it with std::get
#include<tuple>
#include<iostream>
template <typename... T> void fill(std::tuple<T...> values) {
std::cout << std::tuple_size<T...>::value << '\n';
//std::cout << std::get<0>(values) << '\n';
//std::cout << std::get<1>(values) << '\n';
}
int main() {
fill(std::make_tuple(2.));
fill(std::make_tuple(2., 5));
}
tuple_size seems not suitable to be used (https://en.cppreference.com/w/cpp/utility/tuple/tuple_size)
Lets look at the example in the provided reference:
template <class T>
void test(T t)
{
int a[std::tuple_size<T>::value]; // can be used at compile time
std::cout << std::tuple_size<T>::value << '\n'; // or at run time
}
int main()
{
test(std::make_tuple(1, 2, 3.14));
}
From this example (as well as from the reference itself, see e.g. the second declaration), it could be deduced that the template argument to std::tuple_size is the tuple type.
As in (in your case)
std::cout << std::tuple_size<std::tuple<T...>>::value << '\n';
// ^^^^^^^^^^^^^^^^
// Note: The tuple type is used here

Is it ok to use ternary operator in C++ streams?

The following code:
#include <iostream>
using namespace std;
struct A{int number=10;};
int main()
{
A* a = new A();
cout<<"A val: "<< a==nullptr?"":a->number<<endl;
}
compiling on gcc 4.7 with c++11 gives:
error: invalid operands of types 'int' and '' to binary 'operator <<'
I do not understand why, what would be to proper way to do it? I want to keep null checks as short as possible as I expect them to be very common.
First: yes, you can use the ternary operator for an std::ostream, but beware of operator precedence. If you are going to do so, you need to do something like this:
cout << "My name is: " << (my != nullptr ? my->name() : "don't know") << '\n';
In other words, encapsulate the ternary expression in parentheses.
Second, the second and third operands must be convertible to the same type. In other words, your example won't work because you are trying to insert a string literal ("") if a is null, or the actual number (a->number, which is of type int) if a is not null.
Third, you need to fix the syntax. But #quamrana already addressed that one.
You are finding that operator << binds differently than you expect.
Use:
cout << "A val: " << (a==nullptr ? "" : a->number) << endl;
(or have you just made a typo and missed the : from ?:)

Passing variables between functions doesnt work

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.

Is it possible/legal to return reference to input temporary arguments which are passed by reference

My question is : is it legal to return a reference to an input variable which is passed by reference.
I borrow the example from C++: Life span of temporary arguments? and return by rvalue reference
#include <iostream>
#include <string>
class MatrixClass
{
public:
int m_value;
std::string m_str;
MatrixClass(int a)
{
m_value = a;
std::cout << "hello: " << m_value << '\n';
}
MatrixClass(const MatrixClass& A)
{
m_value = A.m_value;
std::cout << "hello: " << m_value << '\n';
if (A.m_str == "temp_in_*")
{
std::cout << "string: " << "copied from temp_in_*" << '\n';
}
}
void operator=(const MatrixClass& A)
{
m_value = A.m_value;
std::cout << "hello: " << m_value << '\n';
if (A.m_str == "temp_in_*")
{
std::cout << "string: " << "copied from temp_in_*" << '\n';
}
}
~MatrixClass()
{
std::cout << "bye: " << m_value << '\n';
if (m_str == "temp_in_*")
{
std::cout << "string: " << "temp_in_*" << '\n';
}
}
};
MatrixClass& operator+(MatrixClass& tempClassA, MatrixClass& tempClassB)
{
tempClassA.m_value += tempClassB.m_value;
return tempClassA;
}
MatrixClass operator*(MatrixClass& tempClassA, MatrixClass& tempClassB)
{
MatrixClass Temp(101010);
Temp.m_value = tempClassA.m_value * tempClassB.m_value;
Temp.m_str = "temp_in_*";
return Temp;
}
int main()
{
MatrixClass A1(2);
MatrixClass A2(3);
MatrixClass A3(10);
MatrixClass A4(11);
MatrixClass A5(12);
std::cout << "start of expression " << '\n';
MatrixClass A6(0);
A6 = A1 * A2 + A3 * A4 + A5 * A6;
std::cout << "end of expression " << '\n';
std::cout << "A6.m_value: " << A6.m_value << '\n';
std::system("pause");
}
the operator return a reference to its input which is a temporary variable, and pass
it to another operator: operator*(A1, A2) return a temporary variable, also operator*(A3, A4), operator*(A5, A6)
Is there any problem with the lifetime of the temporary variables ? I am developing a Matrix class.
What happens if the expression is more complicated, such as:
(A+B*C)*((A*B + C)*A)
A general question is (take from return by rvalue reference)
is this possible:
change
A compute(A&& v)
{
(do something to v)
return v;
}
to
A& compute(A& v)
{
(do something to v)
return v;
}
Yes, it is legal for a function to return references to input parameters, in the sense that it will compile and there are many uses where it will work without problems. The lifetime of any temporaries created in an expression is the lifetime of the full expression or statement, so as long as the reference is not used beyond the expression, the usage should work fine. It is somewhat risky, though, because the caller may not be aware of the reference propagation the function does, and the special rules for extension of temporary lifetimes don't generally apply when the reference is passed through an intermediary function.
Your examples involve modifying and returning a reference to non-const lvalue instance. These types of uses, in general, will be harder to run into the pitfalls than references to const or references to rvalues. A reference to non-const lvalue can't be bound to a temporary (at least not without going through some hoops to trick the compiler), so you will generally have to pass an actual l-value (non-temporary) named variable (or other long-lived object) into them. When that reference is then passed out of the function as a return value, it will refer to whatever long-lived object was passed in. (You can still get into trouble if you don't properly manage lifetimes, of course, but at least the lifetimes we're talking about in this case are generally more than a single statement/expression.)
If you pass rvalue references through your function, and especially if they get translated to a non-const lvalue somewhere down the expression tree (which is somewhat easy to do since the language, as a safety feature, decays rvalues into lvalues whenever they're bound to a name), the temporary nature of the reference can be lost and it is easier to accidentally bind the reference to a long-lived reference, which would outlive the temporary that it is bound to (which generally won't live beyond the statement/full-expression in which it is created). This is why I generally favor returning (and usually passing) r-values by value rather than by reference. Then, the compiler is more aware of the lifetime issues and the usages are generally more foolproof. In many cases, the compiler can elide the move constructions anyway, and when it can't, moves are generally cheap.

Resources