Pass by reference to a function accepting a universal reference - c++

I am trying to use an API which sets a value of a variable based on an HTTP call. The function in which I can set the variable which will be set upon an HTTP Call is of type T&&. I would like to access this variable on a different thread. I tried to simplify the problem and represent it in the following code, as two threads, accessing a variable the same way.
#include <iostream>
#include <thread>
#include <chrono>
class Values
{
public:
int i;
std::string s;
};
template<typename T>
void WriteCycle(T&& i)
{
using namespace std::chrono_literals;
while (true)
{
i++;
std::cout << i << std::endl;
std::this_thread::sleep_for(500ms);
}
}
template<typename T>
void ReadCycle(T&& i)
{
using namespace std::chrono_literals;
while (true)
{
std::cout << i << std::endl;
std::this_thread::sleep_for(500ms);
}
}
int main() {
auto v = new Values();
std::thread t1(WriteCycle<int>, v->i);
std::thread t2(ReadCycle<int>, v->i);
t1.join();
t2.join();
}
Currently the read thread does not see any change in the variable. I read up an perfect forwarding, move semnatics and forwardin references, but I did not get it (I mostly program dotnet, my c++ knowledge is pre C++11). I tried all combinations of std::move, std::ref and std::forward but I cannot get the read thread to see the change of the write thread. Is there a way to solve this, without changing the T&& input type of the functions (since that is part of the API I am trying to use)? How to solve this in a thread-safe way?

Such notation:
template<typename T>
void WriteCycle(T&& i)
Doesn't really mean an rvalue reference, it means a universal reference, which could be an lvalue reference or rvalue reference depending on what kind of data you pass.
In your case it turns into just an lvalue reference, so it has nothing to do with move semantic. The problem is that thread constructor is not quite friendly with references and you may want just to use std::ref to get it round:
auto myRef = std::ref(v->i);
std::thread t1(WriteCycle<&int>, myRef);
std::thread t2(ReadCycle<&int>, myRef);
However it still won't be perfect, because you want to synchronize between threads with use of mutexes or atomic values

Related

Is it still valid when the variable passed to `std::async` is out of scope?

Is the code snippet below legal? What worries me is when factorial is invoked the fut_num may be already out of scope.
#include <future>
#include <vector>
#include <iostream>
//int factorial(std::future<int> fut) //works, because there is a move constructor
int factorial(std::future<int>&& fut)
{
int res = 1;
int num = fut.get();
for(int i=num; i>1; i--)
{
res *= i;
}
return res;
}
int main()
{
std::promise<int> prs;
std::vector<std::future<int>> vec;
{
std::future<int> fut_num{prs.get_future()};
vec.push_back(std::async(std::launch::async, factorial, std::move(fut_num)));
} //`fut_num` is out of range now.
prs.set_value(5);
for(auto& fut: vec)
{
std::cout << fut.get() << std::endl;
}
}
And the same question about similar code snippet:
#include <future>
#include <vector>
#include <iostream>
//int factorial(std::future<int> fut) //works, because there is a move constructor
int factorial(std::future<int>& fut)
{
int res = 1;
int num = fut.get();
for(int i=num; i>1; i--)
{
res *= i;
}
return res;
}
int main()
{
std::promise<int> prs;
std::vector<std::future<int>> vec;
{
std::future<int> fut_num{prs.get_future()};
vec.push_back(std::async(std::launch::async, factorial, std::ref(fut_num)));
} //`fut_num` is out of range now.
prs.set_value(5);
for(auto& fut: vec)
{
std::cout << fut.get() << std::endl;
}
}
My two cents about these code snippets:
1.The former code snippet is legal, since std::async copies std::move(fut_num)(i.e. std::move(fut_num) is passed by value to std::async). So there is a local fut_num when fcatorical is called.
2.The latter one is illegal, since fut_num is passed as a reference to std::async. When fut_num is out of scope, it's illegal to call functions which uses fut_num.
The first one is fine, the second one is not.
std::async with std::launch::async uses the same procedure of invoking the thread function as the constructor of std::thread does. Both effectively execute
std::invoke(auto(std::forward<F>(f)), auto(std::forward<Args>(args))...);
in the new thread, but with the auto(...) constructions executing in the context of the calling thread.
Here F/Args... are the (other) template parameters with corresponding forwarding-reference function parameters F&& f/Args&&... args and auto has the new C++23 meaning which creates a prvalue/temporary of the decayed argument's type from the argument.
See [futures.async]/4.1.
This means there will be unnamed copies constructed for all arguments which live in the new thread until after the thread function invocation returns.
So with std::move(fut_num), there will actually be another std::future<int> object which will be move-constructed from fut_num and live until the thread ends execution. factorial will be passed a reference to this unnamed object.
With std::ref(fut_num) you are explicitly by-passing this mechanism protecting you from passing references to the objects in the constructing thread.
The constructor will still make a decayed copy of type std::reference_wrapper<std::future<int>> from the argument, but that object will just contain a reference referring to fut_num in the main thread.
std::invoke will then unwrap the std::reference_wrapper before passing to factorial and the fut argument will refer to fut_num in the main thread, which is then destroyed without any synchronization, causing undefined behavior as it is also accessed in the factorial function.
It either case it doesn't matter whether factorial takes the argument by-reference or by-value. Nothing about the above reasoning changes.

Is it ok to call myfunc(make_shared<int>(0)) to a function receiving a weak_prt?

I'm having a function that takes a weak_ptr<> and I pass my shared_ptr<> in the function.
#include <memory>
#include <iostream>
void takeweak(std::weak_ptr<int> wp) {
std::cout << wp.use_count() << std::endl; // prints 1
}
int main() {
takeweak(std::make_shared<int>());
return 0;
}
Is this working by luck or it is working by design?
Do I have a copy of the shared pointer living throughout the main() scope function? Or Will the shared pointer live throughout the scope of takeweak() body (up to its stack unwind)?
Is it probable that this behavior going to break in a new version of the compiler or the language standard?
Related question: Different behaviour while passing shared_ptr to weak_ptr in thread functions and normal functions

lambda's captured variable is reset

I'm trying to use lambdas inside a project but I think I'm missing something about the closure's scope. I tested this piece of code which in some way is a simplification of my problem.
#include <iostream>
#include <functional>
using namespace std;
void tester_wrapper(std::function<int(void)> cb, int counter){
if (counter == 10)
return;
else{
cout << cb() << endl;
tester_wrapper(cb, counter + 1);
}
}
void tester(std::function<int(void)> cb){
tester_wrapper(cb, 0);
}
int main()
{
auto getNum = ([](int starter) {
return [starter]() mutable {
return ++starter;
};
})(1);
tester(getNum);
tester(getNum);
}
After the first call to tester the captured variable starter is reset so that the same output is printed twice.
What should I do in order to avoid this behaviour of the inner counter(starter) of the lambda? Essentially the second call to tester has to print 10 numbers starting from 12 instead of 2.
EDIT
Thank you for the answers. I have not considered that I was passing a copy to tester_wrapper, so I've found this solution:
#include <iostream>
#include <functional>
using namespace std;
std::function<int(void)> mylambda(int starter){
return [starter]() mutable {
return ++starter;
};
}
void tester_wrapper(const std::function<int(void)>& cb, int counter){
if (counter == 10)
return;
else{
cout << cb() << endl;
tester_wrapper(cb, counter + 1);
}
}
void tester(const std::function<int(void)>& cb){
tester_wrapper(cb, 0);
}
int main()
{
/*auto getNum = ([](int starter) {
return [starter]() mutable {
return ++starter;
};
})(1);*/
auto getNum = mylambda(1);
tester(getNum);
tester(getNum);
}
However, now I can't understand why the old getNum print the same output while it's different using an "external" function, which is mylambda.
(Am I supposed to post a new question for this?)
The variable isn't reset, it's a different copy of the variable. In fact, there are a bunch copies. The first is in the state of the lambda you create. The second is created when the first std::function is constructed. You must remember that it copies the callable it receives into itself. So each invocation of tester starts a chain of copies. One way to get around it, is to pass the lambda inside a std::reference_wrapper.
tester(std::ref(getNum));
tester(std::ref(getNum));
The reference wrapper will be copied, but all copies will refer to the same lambda object, getNum.
Now, assuming you intend to create many different objects like getNum, a std::function and the type erasure it provides are a reasonable course of action to avoid possible code bloat. The thing to remember is to not create superfluous copies. So tester accepting by value is legitimate, but tester_wrapper should accept by reference instead. That way, you'll only pay for the type erasure in the one place you need it, at the API boundary.
The argument getNum you're passing to tester is being copied by std::function<int(void)>. That is, std::function<int(void)> does not store the original getNum, instead it stores a copy.
#StoryTeller and #Edgar already suggested two solutions. Here is third one:
template<typename Callback>
void tester_wrapper(Callback && cb, int counter){
if (counter == 10)
return;
else{
cout << cb() << endl;
tester_wrapper(cb, counter + 1);
}
}
template<typename Callback>
void tester(Callback && cb){
tester_wrapper(std::forward<Callback>(cb), 0);
}
Now there is no copy, as both functions accept the argument by reference.
By the way, this code is likely to be faster than the other two, as other two continue to use std:function which has one virtual call or equivalent to invoke the stored callable.
Hope that helps.
One possible solution is to create a separate variable starter and then capture it by reference so the lambda changes the actual variable:
auto starter = 0;
auto getNum = [&starter]() {
return ++starter;
};
Then you just call:
tester(getNum);
tester(getNum);
The output will be numbers from 1 to 20.

Create and return a function within another function [duplicate]

I mean something like:
int main()
{
void a()
{
// code
}
a();
return 0;
}
Modern C++ - Yes with lambdas!
In current versions of c++ (C++11, C++14, and C++17), you can have functions inside functions in the form of a lambda:
int main() {
// This declares a lambda, which can be called just like a function
auto print_message = [](std::string message)
{
std::cout << message << "\n";
};
// Prints "Hello!" 10 times
for(int i = 0; i < 10; i++) {
print_message("Hello!");
}
}
Lambdas can also modify local variables through **capture-by-reference*. With capture-by-reference, the lambda has access to all local variables declared in the lambda's scope. It can modify and change them normally.
int main() {
int i = 0;
// Captures i by reference; increments it by one
auto addOne = [&] () {
i++;
};
while(i < 10) {
addOne(); //Add 1 to i
std::cout << i << "\n";
}
}
C++98 and C++03 - Not directly, but yes with static functions inside local classes
C++ doesn't support that directly.
That said, you can have local classes, and they can have functions (non-static or static), so you can get this to some extend, albeit it's a bit of a kludge:
int main() // it's int, dammit!
{
struct X { // struct's as good as class
static void a()
{
}
};
X::a();
return 0;
}
However, I'd question the praxis. Everyone knows (well, now that you do, anyway :)) C++ doesn't support local functions, so they are used to not having them. They are not used, however, to that kludge. I would spend quite a while on this code to make sure it's really only there to allow local functions. Not good.
For all intents and purposes, C++ supports this via lambdas:1
int main() {
auto f = []() { return 42; };
std::cout << "f() = " << f() << std::endl;
}
Here, f is a lambda object that acts as a local function in main. Captures can be specified to allow the function to access local objects.
Behind the scenes, f is a function object (i.e. an object of a type that provides an operator()). The function object type is created by the compiler based on the lambda.
1 since C++11
Local classes have already been mentioned, but here is a way to let them appear even more as local functions, using an operator() overload and an anonymous class:
int main() {
struct {
unsigned int operator() (unsigned int val) const {
return val<=1 ? 1 : val*(*this)(val-1);
}
} fac;
std::cout << fac(5) << '\n';
}
I don't advise on using this, it's just a funny trick (can do, but imho shouldn't).
2014 Update:
With the rise of C++11 a while back, you can now have local functions whose syntax is a little reminiscient of JavaScript:
auto fac = [] (unsigned int val) {
return val*42;
};
For a recursive function, compile-time type deduction is not supported:
function<int(int)> factorial{ [&](int n)
{
return (n == 1 || n == 0) ? 1 : factorial(n - 1) * n;
} };
You can't have local functions in C++. However, C++11 has lambdas. Lambdas are basically variables that work like functions.
A lambda has the type std::function (actually that's not quite true, but in most cases you can suppose it is). To use this type, you need to #include <functional>. std::function is a template, taking as template argument the return type and the argument types, with the syntax std::function<ReturnType(ArgumentTypes)>. For example, std::function<int(std::string, float)> is a lambda returning an int and taking two arguments, one std::string and one float. The most common one is std::function<void()>, which returns nothing and takes no arguments.
Once a lambda is declared, it is called just like a normal function, using the syntax lambda(arguments).
To define a lambda, use the syntax [captures](arguments){code} (there are other ways of doing it, but I won't mention them here). arguments is what arguments the lambda takes, and code is the code that should be run when the lambda is called. Usually you put [=] or [&] as captures. [=] means that you capture all variables in the scope in which the value is defined by value, which means that they will keep the value that they had when the lambda was declared. [&] means that you capture all variables in the scope by reference, which means that they will always have their current value, but if they are erased from memory the program will crash. Here are some examples:
#include <functional>
#include <iostream>
int main(){
int x = 1;
std::function<void()> lambda1 = [=](){
std::cout << x << std::endl;
};
std::function<void()> lambda2 = [&](){
std::cout << x << std::endl;
};
x = 2;
lambda1(); //Prints 1 since that was the value of x when it was captured and x was captured by value with [=]
lambda2(); //Prints 2 since that's the current value of x and x was captured by reference with [&]
std::function<void()> lambda3 = [](){}, lambda4 = [](){}; //I prefer to initialize these since calling an uninitialized lambda is undefined behavior.
//[](){} is the empty lambda.
{
int y = 3; //y will be deleted from the memory at the end of this scope
lambda3 = [=](){
std::cout << y << endl;
};
lambda4 = [&](){
std::cout << y << endl;
};
}
lambda3(); //Prints 3, since that's the value y had when it was captured
lambda4(); //Causes the program to crash, since y was captured by reference and y doesn't exist anymore.
//This is a bit like if you had a pointer to y which now points nowhere because y has been deleted from the memory.
//This is why you should be careful when capturing by reference.
return 0;
}
You can also capture specific variables by specifying their names. Just specifying their name will capture them by value, specifying their name with a & before will capture them by reference. For example, [=, &foo] will capture all variables by value except foo which will be captured by reference, and [&, foo] will capture all variables by reference except foo which will be captured by value. You can also capture only specific variables, for example [&foo] will capture foo by reference and will capture no other variables. You can also capture no variables at all by using []. If you try to use a variable in a lambda that you didn't capture, it won't compile. Here is an example:
#include <functional>
int main(){
int x = 4, y = 5;
std::function<void(int)> myLambda = [y](int z){
int xSquare = x * x; //Compiler error because x wasn't captured
int ySquare = y * y; //OK because y was captured
int zSquare = z * z; //OK because z is an argument of the lambda
};
return 0;
}
You can't change the value of a variable that was captured by value inside a lambda (variables captured by value have a const type inside the lambda). To do so, you need to capture the variable by reference. Here is an exampmle:
#include <functional>
int main(){
int x = 3, y = 5;
std::function<void()> myLambda = [x, &y](){
x = 2; //Compiler error because x is captured by value and so it's of type const int inside the lambda
y = 2; //OK because y is captured by reference
};
x = 2; //This is of course OK because we're not inside the lambda
return 0;
}
Also, calling uninitialized lambdas is undefined behavior and will usually cause the program to crash. For example, never do this:
std::function<void()> lambda;
lambda(); //Undefined behavior because lambda is uninitialized
Examples
Here is the code for what you wanted to do in your question using lambdas:
#include <functional> //Don't forget this, otherwise you won't be able to use the std::function type
int main(){
std::function<void()> a = [](){
// code
}
a();
return 0;
}
Here is a more advanced example of a lambda:
#include <functional> //For std::function
#include <iostream> //For std::cout
int main(){
int x = 4;
std::function<float(int)> divideByX = [x](int y){
return (float)y / (float)x; //x is a captured variable, y is an argument
}
std::cout << divideByX(3) << std::endl; //Prints 0.75
return 0;
}
No.
What are you trying to do?
workaround:
int main(void)
{
struct foo
{
void operator()() { int a = 1; }
};
foo b;
b(); // call the operator()
}
Starting with C++ 11 you can use proper lambdas. See the other answers for more details.
Old answer: You can, sort-of, but you have to cheat and use a dummy class:
void moo()
{
class dummy
{
public:
static void a() { printf("I'm in a!\n"); }
};
dummy::a();
dummy::a();
}
No, it's not allowed. Neither C nor C++ support this feature by default, however TonyK points out (in the comments) that there are extensions to the GNU C compiler that enable this behavior in C.
You cannot define a free function inside another in C++.
As others have mentioned, you can use nested functions by using the gnu language extensions in gcc. If you (or your project) sticks to the gcc toolchain, your code will be mostly portable across the different architectures targeted by the gcc compiler.
However, if there is a possible requirement that you might need to compile code with a different toolchain, then I'd stay away from such extensions.
I'd also tread with care when using nested functions. They are a beautiful solution for managing the structure of complex, yet cohesive blocks of code (the pieces of which are not meant for external/general use.) They are also very helpful in controlling namespace pollution (a very real concern with naturally complex/long classes in verbose languages.)
But like anything, they can be open to abuse.
It is sad that C/C++ does not support such features as an standard. Most pascal variants and Ada do (almost all Algol-based languages do). Same with JavaScript. Same with modern languages like Scala. Same with venerable languages like Erlang, Lisp or Python.
And just as with C/C++, unfortunately, Java (with which I earn most of my living) does not.
I mention Java here because I see several posters suggesting usage of classes and class' methods as alternatives to nested functions. And that's also the typical workaround in Java.
Short answer: No.
Doing so tend to introduce artificial, needless complexity on a class hierarchy. With all things being equal, the ideal is to have a class hierarchy (and its encompassing namespaces and scopes) representing an actual domain as simple as possible.
Nested functions help deal with "private", within-function complexity. Lacking those facilities, one should try to avoid propagating that "private" complexity out and into one's class model.
In software (and in any engineering discipline), modeling is a matter of trade-offs. Thus, in real life, there will be justified exceptions to those rules (or rather guidelines). Proceed with care, though.
All this tricks just look (more or less) as local functions, but they don't work like that. In a local function you can use local variables of it's super functions. It's kind of semi-globals. Non of these tricks can do that. The closest is the lambda trick from c++0x, but it's closure is bound in definition time, not the use time.
Let me post a solution here for C++03 that I consider the cleanest possible.*
#define DECLARE_LAMBDA(NAME, RETURN_TYPE, FUNCTION) \
struct { RETURN_TYPE operator () FUNCTION } NAME;
...
int main(){
DECLARE_LAMBDA(demoLambda, void, (){
cout<<"I'm a lambda!"<<endl;
});
demoLambda();
DECLARE_LAMBDA(plus, int, (int i, int j){
return i+j;
});
cout << "plus(1,2)=" << plus(1,2) << endl;
return 0;
}
(*) in the C++ world using macros is never considered clean.
But we can declare a function inside main():
int main()
{
void a();
}
Although the syntax is correct, sometimes it can lead to the "Most vexing parse":
#include <iostream>
struct U
{
U() : val(0) {}
U(int val) : val(val) {}
int val;
};
struct V
{
V(U a, U b)
{
std::cout << "V(" << a.val << ", " << b.val << ");\n";
}
~V()
{
std::cout << "~V();\n";
}
};
int main()
{
int five = 5;
V v(U(five), U());
}
=> no program output.
(Only Clang warning after compilation).
C++'s most vexing parse again
Yes, and you can do things with them that even C++20 Lambdas don't support. Namely, pure recursive calls to themselves & related functions.
For example, the Collatz Conjecture is that a certain simple recursive function will ultimately produce "1" for ANY positive integer N. Using an explicit local struct and functions, I can write a single self-contained function to run the test for any "N".
constexpr std::optional<int> testCollatzConjecture(int N) {
struct CollatzCallbacks {
constexpr static int onEven(int n) {
return recurse(n >> 1); // AKA "n/2"
}
constexpr static int onOdd(int n) {
if(n==1) return 1; // Break recursion. n==1 is only possible when n is odd.
return recurse(3 * n + 1);
}
constexpr static int recurse(int n) {
return (n%2) ? onOdd(n) : onEven(n); // (n%2) == 1 when n is odd
}
};
// Error check
if(N < 0) return {};
// Recursive call.
return CollatzCallbacks::recurse(N);
}
Notice some things that even c++20 lambdas couldn't do here:
I didn't need std::function<> glue OR lambda captures ("[&]") just to enable my local recursive functions call themselves, or each other. I needed 3 plain-old-functions with names, and that's all I had to write.
My code is more readable and (due to (1)) will also run much faster.
I cleanly separate the recursive logic in "CollatzCallbacks" from the rest of "testCollatzConjecture". It all runs in an isolated sandbox.
I was able to make everything "constexpr" and state-less, so it can all run at compile time for any constant value. AFAIK I'd need c++23 just to achieve the recursion part with state-less lambdas.
Remember: Lambda functions are really just compiler-generated local structs like "CollatzCallbacks", only they're unnamed and only have a single "operator()" member function. You can always write more complex local structs and functions directly, especially in cases like this where you really need them.

Use of deleted function with boost::bind

I'm currently doing the boost asio tutorial, and I'm running into a problem with bind:
Of course the default code works: http://www.boost.org/doc/libs/1_55_0/doc/html/boost_asio/tutorial/tuttimer3/src.html
but when I'm trying to use references instead of pointers in the print function, I get compiler errors:
error: use of deleted function ‘asio::basic_deadline_timer<boost::posix_time::ptime>::basic_deadline_timer(const asio::basic_deadline_timer<boost::posix_time::ptime>&)’
t.async_wait(boost::bind(do_sth1,asio::placeholders::error,t, count));
My modified code:
#include <iostream>
#include <asio.hpp>
#include <boost/bind.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
void do_sth1(const asio::error_code& ,asio::deadline_timer& t, int& count )
{
if(count<=5){
(count)++;
t.expires_at(t.expires_at()+boost::posix_time::seconds(2));
t.async_wait(boost::bind(do_sth1,asio::placeholders::error,t, count));
}
std::cout<<count<<"\n";
}
void do_sth2(const asio::error_code& ){
std::cout<<"Yo\n";
}
int main()
{
int count =0;
asio::io_service io;
asio::deadline_timer t1(io, boost::posix_time::seconds(1));
asio::deadline_timer t2(io, boost::posix_time::seconds(3));
t1.async_wait(boost::bind(do_sth1,asio::placeholders::error,t1,count));
t2.async_wait(do_sth2);
io.run();
std::cout << "Hello, world!\n";
return 0;
}
Deleted functions have been introduced only recently to C++ -- see e.g. here on MSDN. Previously this was worked around by declaring the method as private. Whatever the way it is done, it means that someone declared an otherwise implicitly created method as deleted, so that nobody could (even accidentally) call it. This is used for example to disallow copying objects which it does not make sense to copy (by deleting the copy constructor).
This is exactly your case, as the deleted function's name ‘asio::basic_deadline_timer::basic_deadline_timer(const asio::basic_deadline_timer&) indeed reveals that a copy constructor was supposed to be called. boost::deadline_timers cannot be copied.
But why is the timer object being copied? Because boost::bind by default stores the bound parameters by value. If you need to pass a reference, you need to use boost::ref as follows:
t1.async_wait(boost::bind(do_sth1,asio::placeholders::error,boost::ref(t1),boost::ref(count)));
I.e. even for the count variable, which would not cause a compiler error, but wouldn't work (would not modify the variable in main()).