init-capture for rvalue reference in Visual Studio 2013 - c++

I want use .net's System.Threading.Tasks.Task.ContinueWith in C++, so I write the following function..
#include <iostream>
#include <functional>
#include <future>
template <typename Func, typename Ret>
auto continue_with(std::future<Ret> &&fu, Func func)
-> std::future<decltype(func(fu.get()))>
{
return std::async(
[fu = std::move(fu), func]() mutable { return func(fu.get()); }
);
}
template <typename Func>
auto continue_with(std::future<void> &&fu, Func func)
-> std::future<decltype(func())>
{
return std::async(
[fu = std::move(fu), func]() mutable { fu.get(); return func(); }
);
}
int main()
{
std::future<void> fu = std::async([]{ std::cout << "fu" << std::endl; });
std::future<void> fu2 = continue_with(
std::move(fu),
[]{ std::cout << "fu2" << std::endl; }
);
fu2.get();
std::cout << "fu continue complete" << std::endl;
std::future<int> retfu = std::async([]{ std::cout << "retfu" << std::endl; return 3; });
std::future<int> retfu2 = continue_with(
std::move(retfu),
[](int result){ std::cout << "retfu2 " << result << std::endl; return result + 1; }
);
int ret = retfu2.get();
std::cout << "retfu continue complete : " << ret << std::endl;
std::cin.get();
}
This code works on gcc 4.8.2 with -std=c++1y. (I don't know why, but it works with -std=c++11, too)
But it doesn't work on VC++ 2013. I guess it's because init-capture, a C++14 feature. How can I run this code with VC++ 2013?
(I want to use lambda, so please don't tell me "use just function-object struct!")
(I tried Move capture in lambda, but it doesn't work..)
(I'll appreciate if you not only answer my question but also imporve my code)

Unfortunately, this feature was not present yet in Visual Studio 2013. It was released in June 2014 with the Visual Studio "14" CTP (community tech preview, which is alpha-quality and not ready for production code). To quote:
Here are the improvements for Visual C++:
Generalized lambda capture: You can assign the result of evaluating an
expression to a variable in the capture clause of a lambda. This
allows an instance of a move-only type to be captured by value.
As was pointed out in the comments: as a work-around for Visual Studio 2013, you can make your own function object with local variables initialized through the constructor. Yes, this sucks, but it has been the standard trick before lambdas were invented. It was also the case with polymorphic lambdas until they were supported (workaround: function object with templated operator()) and currently with the currently disallowed constexpr lambdas (workaround: constexpr function object of literal type).

2 other options exist, using std::bind and writing a move on copy wrapper.
so you could do
return std::async(std::bind(
[func](std::future<void> & fu) mutable { fu.get(); return func(); },
std::move(fu)
);
The move on copy wrapper I can just point you to How to capture std::unique_ptr "by move" for a lambda in std::for_each

Related

C++: Can you do a lambda implicit copy capture plus explicit copy capture?

Trying to keep an object alive (but not needing to reference the shared_ptr to do so) I found myself writing stuff like this:
void ClassDerivedFromSharedFromThis::countdown(ThreadPool &pool, std::string name){
auto self = shared_from_this();
pool.then([=, self]{
for(int i = 0;i < 10;++i){
atomic_cout() << "Hey [" << name << "]! Our counter is: " << atomicCounter++ << "\n";
}
});
}
But then got an error in visual studio that said I couldn't copy-capture explicitly because I was already copy-capturing implicitly... This forced me to write:
void countdown(ThreadPool &pool, std::string name){
auto self = shared_from_this();
pool.then([=]{
self; //Capture self.
for(int i = 0;i < 10;++i){
atomic_cout() << "Hey [" << name << "]! Our counter is: " << atomicCounter++ << "\n";
}
});
}
I know this works, but it feels wrong. Since I only need the side-effect of the shared_ptr ownership and do not need to reference it directly I would like to express this in the capture list instead of the lambda body.
In my real code I have about 5 or 6 variables I wanted to capture across a couple nested lambdas in network code and implicit capture was way nicer and easier to edit.
My question is: is this standard behaviour or Visual Studio 2015's own take on lambda capture limitations? Do newer versions of the standard allow for this, or has anyone talked about it?
Yes this is standard behavior. From C++14 (N4140) [expr.prim.lambda]/8
If a lambda-capture includes a capture-default that is =, each simple-capture of that lambda-capture shall be of the form “& identifier”.
So if you have [=] then any other capture you do must be done by reference like
[=, &some_var]{} // copy all implicitly but explicitly capture some_var by reference
The rules do change in C++17 but it is to allow
[=, *this]{};
Which will capture a copy of the object into the lambda.
You can do what you want with an init-capture:
void ClassDerivedFromSharedFromThis::countdown(ThreadPool &pool, std::string name){
pool.then([=, self=shared_from_this()]{
for(int i = 0;i < 10;++i){
atomic_cout() << "Hey [" << name << "]! Our counter is: " << atomicCounter++ << "\n";
}
});
}
With the bonus that you don't have to declare self separately.

Creating a function alias

EDIT: This question was originally titled "Using std::bind to create inline function," but that's not really what I'm after: I just want a simple way to alias functions.
I would like to expose std::chrono::high_resolution_clock::now as a standalone function. That is, I would like to do the following:
auto current_time = std::bind(std::chrono::high_resolution_clock::now);
Unfortunately, since this is in a header file, it results in multiple definitions of current_time at link-time. Is there a way to return an inline function from std::bind?
Here's what I do if I want to create a simple function alias
constexpr auto &&now = std::chrono::high_resolution_clock::now;
and if I want to create a full wrapper alias that will be inlined
template<typename ... Args>
inline constexpr auto now(Args &&... args) -> decltype(std::chrono::high_resolution_clock::now(std::forward<Args>(args)...)){
return std::chrono::high_resolution_clock::now(std::forward<Args>(args)...);
}
The reason why I use a universal reference auto&& in the alias definition is because of the possibility of addressof(now) == addressof(std::chrono::high_resolution_clock::now).
On my system with G++ 4.9.2 running this:
constexpr auto &&now_ref = std::chrono::high_resolution_clock::now;
constexpr auto now_var = std::chrono::high_resolution_clock::now;
template<typename ... Args>
inline constexpr auto now_wrapper(Args &&... args)
-> decltype(std::chrono::high_resolution_clock::now(std::forward<Args>(args)...)){
return std::chrono::high_resolution_clock::now(std::forward<Args>(args)...);
}
int main(int argc, char *argv[]){
std::cout << std::hex << std::showbase;
std::cout << (uintptr_t)std::addressof(std::chrono::high_resolution_clock::now) << '\n';
std::cout << (uintptr_t)std::addressof(now_wrapper<>) << '\n';
std::cout << (uintptr_t)std::addressof(now_var) << '\n';
std::cout << (uintptr_t)std::addressof(now_ref) << '\n';
}
I get the following results:
0x4007c0
0x400a50
0x400ae8
0x4007c0
Showing that only the auto&& is actually a direct alias of the function, whereas all other methods have some level of indirection. (although, after compilation they may be replaced by inlined function calls. maybe.)
I don't think there is anyway to do this as bind is not constexpr.
Also lambdas are not constexpr-able.
Edit: there is this trick to make a constexpr-like lambda http://pfultz2.com/blog/2014/09/02/static-lambda/
Adding another answer 'cause it takes a very different tack to what you want.
std::bind isn't necessary in this case, because no 'binding' is happening.
However I feel this could lead to some confusing problems down the line, since current_time isn't really an alias in the same way that using delcarations are.
#include <iostream>
#include <chrono>
using namespace std;
auto constexpr current_time = std::chrono::high_resolution_clock::now;
int main() {
auto now = current_time();
cout << std::chrono::system_clock::to_time_t(now) << endl;
return 0;
}
Using GCC it is possible to create a "function alias", but only for functions which are defined in the same translation unit and for which you know the mangled name, so it's not possible to do reliably for std::chrono::high_resolution_clock::now()
See the alias attribute at https://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
Keep it simple.
const auto current_time = std::chrono::high_resolution_clock::now;

destructor called before temporary should be out of scope

I have a bit of code which fails under VS2015, but works under GCC. I'm pretty sure the bug is with Visual Studio but want to be sure that my understanding of decltype(auto) is correct.
#include <iostream>
using namespace std;
string zero_params()
{
return "zero_params called.";
}
template< typename F >
auto test1( F f ) -> decltype(auto)
{
return f();
}
int main() {
cout << std::is_rvalue_reference< decltype(test1(zero_params)) >::value << endl;
cout << test1(zero_params) << endl;
cout << "Done!" << endl;
return 0;
}
Under Visual Studio the string returned by zero_params is deduced to be an rvalue reference. Furthermore the destructor of that object is called inside test1() where the return from the call to f happens (which seems a reasonable place to destruct a && object).
Under GCC the string returned is not deduced to be an rvalue reference. The destructor is called after use in the cout statement as I'd expect.
Specifying the return type to be 'string' instead of decltype(auto) under Visual Studio fixes it, as does using remove_reference_t on the return of f() inside test1.
My expectation would be that GCC is correct as the function signature for zero_params() is string, not string&& so I would expect the non-reference to 'bubble up' to the return type of test1 if it uses decltype(auto).
Is this a correct assessment?
LATE EDIT:
Another way I've found to get around this with VS2015 is to wrap the function given to test1 in a lambda:
cout << test1(zero_params) << endl;
to:
cout << test1( [](auto&&... ps) { return zero_params(std::forward<decltype(ps)>(ps)...); } ) << endl;
So based on the comments we can conclude:
This is a bug in VS2015 preview
There are workarounds
The bug has been reported
The bug is that:
The compiler should have deduced the return type to be string
It actually deduced it to be string &&
Thus it destroyed the value prematurely
The workarounds are:
Don't use decltype(auto) for the function's return type
Wrap the function in a lambda expression before passing it in

is it safe to modify variables in the via closure from the inner frame of a lambda that was create from a function that no longer function exists

This works on g++ 4.7
#include <iostream>
#include <functional>
std::function<int()> make_counter() {
return []()->std::function<int()> {
int c=0;
return [=]() mutable ->int {
return c++ ;
};
}();
}
int main(int argc, char * argv[]) {
auto count1= make_counter();
auto count2= make_counter();
std::cout << "count1=" << count1() << std::endl;
std::cout << "count1=" << count1() << std::endl;
std::cout << "count2=" << count2() << std::endl;
std::cout << "count1=" << count1() << std::endl;
std::cout << "count2=" << count2() << std::endl;
return 0;
}
It seems like I should be able to do this because c no longer exists after make_function returns, but it is does
count1=0
count1=1
count1=2
count2=0
count1=3
count2=1
I'm guessing that the [=] makes it so the value of c stored and mutable is allows for the stored value to modified though I just want to make sure.
Valgrind doesn't complain about this at all. Every time I call make_counter, valgrind reports an additional allocation and free, so I assume the lambda meta programming code is inserting the allocation code for the memory for variable . I'm wonder if this is Cxx11 compliant or if it's just g++ specific.
assuming the answer is correct, I could simplify make_counter to
std::function<int()> make_counter() {
int c=0 ;
return [=]() mutable ->int {
return c++ ;
};
}
Yes it is.
By specifying [=] you made a copy of the local variable, and that copy is stashed, somewhere, in the lambda. The expression c++ uses that local copy, which will live as long as the lambda does.
Note that the mutable would not have been necessary had c being referencing an external variable; its presence is made necessary by the fact that c is captured by copy and thus lives within the lambda "body".

C++11 lambda returning lambda

this piece of code is not something unknown to JS developers
function get_counter()
{
return (
function() {
var c = 0;
return function() { return ++c; };
})();
}
it basically creates a which creates different enumerators. So I was wondering if same thing can be done in C++11 with new lambda semantics? I ended up writing this piece of C++ which unfortunately does not compile!
int main()
{
int c;
auto a = [](){
int c = 0;
return [&](){
cout << c++;
};
};
return 0;
}
so I was wondering if there is a workaround to get it compiled and if there is how can compiler make this code run correctly? I mean it has to create separate enumerators but it should also collect garbage (unused c variables).
by the way I'm using VS2012 compiler and it generates this error:
Error 2 error C2440: 'return' : cannot convert from 'main::<lambda_10d109c73135f5c106ecbfa8ff6f4b6b>::()::<lambda_019decbc8d6cd29488ffec96883efe2a>' to 'void (__cdecl *)(void)' c:\users\ali\documents\visual studio 2012\projects\test\test\main.cpp 25 1 Test
Your code has a bug in that it contains a dangling reference; the c reference will refer to the local variable in the outer lambda, which will be destroyed when the outer lambda returns.
You should write it using a mutable by-value lambda capture:
auto a = []() {
int c = 0;
return [=]() mutable {
cout << c++;
};
};
This relies on a post-standard extension to allow multiple statements in a return-type-deducing lambda; Is there a reason on not allowing lambdas to deduce the return type if it contains more than one statement? The easiest way to fix it is to supply a parameter so that the lambda contains only a single statement:
auto a = [](int c) {
return [=]() mutable {
cout << c++;
};
};
Unfortunately default parameters aren't allowed in lambdas, so you'd have to call this as a(0). Alternatively at the cost of readability you could use a nested lambda call:
auto a = []() {
return ([](int c) {
return [=]() mutable {
cout << c++;
};
})(0);
};
The way this works is that when a executes the inner lambda copies all the referenced variables into an instance of its closure type, which here would be something like:
struct inner_lambda {
int c;
void operator()() { cout << c++; }
};
The instance of the closure type is then returned by the outer lambda, and can be invoked and will modify its copy of c when called.
Overall, your (fixed) code is translated to:
struct outer_lambda {
// no closure
struct inner_lambda {
int c; // by-value capture
// non-const because "mutable"
void operator()() { cout << c++; }
}
// const because non-"mutable"
inner_lambda operator()(int c) const {
return inner_lambda{c};
}
};
If you left c as a by-reference capture, this would be:
struct outer_lambda {
// no closure
struct inner_lambda {
int &c; // by-reference capture
void operator()() const { cout << c++; } // const, but can modify c
}
inner_lambda operator()(int c) const {
return inner_lambda{c};
}
};
Here inner_lambda::c is a dangling reference to the local parameter variable c.
It's a natural limitation of C++ that a lambda which captures by reference can't use the captured variable any more, once the variable no longer exists. So even if you get it to compile, you can't return this lambda from the function in which it appears (that also happens to be a lambda, but that's irrelevant), because the automatic variable c is destroyed on return.
I think the code you need is:
return [=]() mutable {
cout << c++;
};
I haven't tested it and I don't know what compiler versions support it, but that's a capture-by-value, with mutable to say that the captured value can be modified by the lambda.
So each time you call a you get a different counter with its own count starting from 0. Each time you call that counter, it increments its own copy of c. As far as I understand Javascript (not far), that's what you want.
I think the problem is that the compiler cannot deduce the return type of the outer lambda (that assigned to a) because it consists of more than a simple one line return. But unfortunately there is also no way to explicitly state the type of the inner lambda. So you will have to return a std::function, which comes with some additional overhead:
int main()
{
int c;
auto a = []() -> std::function<void()> {
int c = 0;
return [=]() mutable {
std::cout << c++;
};
};
return 0;
}
And of course you have to capture by-value, like Steve already explained in his answer.
EDIT: As to why the exact error is that it cannot convert the returned inner lambda to void(*)() (pointer to void() function), I only have some guesses because I don't have much insight into their lambda implementation, which I'm not sure is that stable or standard-conformant at all.
But I think VC at least tries to deduce the return type of the inner lambda and realizes that it returns a callable. But then it somehow incorrectly assumes this inner lambda to not capture (or they are not able to determine the inner lambda's type), so they just make the outer lambda return a simple function pointer, which would indeed work if the inner lambda wouldn't capture anything.
EDIT: And like ecatmur states in his comment, returning a std::function is even neccessary when making an actual get_counter function (instead of a lambda), since normal functions don't have any automatic return type deduction.
The first thing you should know is that even if you get the syntax to compile, the semantics are different. In C++ lambdas that capture by reference capture just a plain reference, that will not extend the lifetime of the object bound by that reference. That is, the lifetime of c is bound to the lifetime of the enclosing lambda:
int main()
{
int c;
auto a = [](){
int c = 0;
return [&](){
return ++c;
};
}(); // Note: added () as in the JS case
std::cout << a() << a();
return 0;
}
After adding the missing () so that the external lambda is evaluated, your problem is that the c that is held by reference in the returned lambda is no longer valid after the evaluation of the full expression.
That being said, it is not too complex to make that work at the cost of an extra dynamic allocation (which would be the equivalent of the JS case):
int main()
{
int c;
auto a = [](){
std::shared_ptr<int> c = std::make_shared<int>(0);
return [=](){
return ++(*c);
};
}(); // Note: added () as in the JS case
std::cout << a() << a();
return 0;
}
That should compile and work as expected. Whenever the internal lambda is released (a goes out of scope) the counter will be freed from memory.
This works on g++ 4.7
#include <iostream>
#include <functional>
std::function<int()> make_counter() {
return []()->std::function<int()> {
int c=0;
return [=]() mutable ->int {
return c++ ;
};
}();
}
int main(int argc, char * argv[]) {
int i = 1;
auto count1= make_counter();
auto count2= make_counter();
std::cout << "count1=" << count1() << std::endl;
std::cout << "count1=" << count1() << std::endl;
std::cout << "count2=" << count2() << std::endl;
std::cout << "count1=" << count1() << std::endl;
std::cout << "count2=" << count2() << std::endl;
return 0;
}
Valgrind doesn't complain about this at all. Every time I call make_counter, valgrind reports an additional allocation and free, so I assume the lambda meta programming code is inserting the allocation code for the memory for variable c (I guess I can check the debugger). I wonder if this is Cxx11 compliant or just g++ specific. Clang 3.0 will not compile this because it doesn't have std::function (maybe I can try using boost function).
I know this is late, but in C++14 and later you can now initiliaze a lambda capture, leading to more simple code:
auto a = []() {
return [c=0]() mutable {
cout << c++;
};
};