In this answer they suggest to use the following code:
#include <iostream>
template <typename F>
class Finally {
F f;
public:
template <typename Func>
Finally(Func&& func) : f(std::forward<Func>(func)) {}
~Finally() { f(); }
Finally(const Finally&) = delete;
Finally(Finally&&) = delete;
Finally& operator =(const Finally&) = delete;
Finally& operator =(Finally&&) = delete;
};
template <typename F>
Finally<F> make_finally(F&& f)
{
return Finally<F>{ std::forward<F>(f) }; // This doesn't compile
//This compiles: return { std::forward<F>(f) };
}
int main()
{
auto&& doFinally = make_finally([&] { std::cout<<", world!\n"; });
std::cout << "Hello";
}
The author linked to a demo that compiles with Clang++/G++ . However, this code does not compile for me in MSVC++2017 .
The error message is:
source_file.cpp(20): error C2280: 'Finally<main::<lambda_9000fb389e10855198e7a01ce16ffa3d>>::Finally(Finally<main::<lambda_9000fb389e10855198e7a01ce16ffa3d>> &&)': attempting to reference a deleted function
source_file.cpp(12): note: see declaration of 'Finally<main::<lambda_9000fb389e10855198e7a01ce16ffa3d>>::Finally'
source_file.cpp(26): note: see reference to function template instantiation 'Finally<main::<lambda_9000fb389e10855198e7a01ce16ffa3d>> make_finally<main::<lambda_9000fb389e10855198e7a01ce16ffa3d>>(F &&)' being compiled
with
[
F=main::<lambda_9000fb389e10855198e7a01ce16ffa3d>
]
So what is the difference between return { std::forward<F>(f) };
and return Finally<F>{ std::forward<F>(f) };
that one compiles, but the other doesn't?