I was trying to compile this code but it fails on C 14
while it works on C 17
#include <cstdio>
#include <utility>
template <typename F>
struct S {
explicit S(F&& fn): fn(std::move(fn)) {}
F fn;
~S() { fn(); }
};
int main(){
S obj([]() noexcept {
std::printf("Foo\n");
});
}
I see that in C 17
the constructor of S
has been invoked as
call S<main::{lambda()#1}>::S(main::{lambda()#1}&&)
which indicates that the compiler deduced the template argument. Is there a way to get this code compiling in C 14
other than doing something as follows?
auto fn = []() noexcept {
std::printf("Foo\n");
};
S<decltype(fn)> obj(std::move(fn));
CodePudding user response:
Class template argument deduction (CTAD) was only introduced in C 17 . You can deduce the argument with a function:
template <typename F>
S<F> make_S(F&& fn) { return S<F>{std::forward<F>(fn)}; }
int main(){
auto obj = make_S([]() noexcept {
std::printf("Foo\n");
});
}
CodePudding user response:
If you can live with a fixed function signature then this works in C 14 too.
#include <functional>
#include <iostream>
#include <utility>
struct S
{
template <typename F>
explicit S(F&& fn) :
m_fn(fn)
{
}
~S()
{
m_fn();
}
private:
std::function<void ()> m_fn;
};
int main() {
S obj([]() noexcept
{
std::cout << "Foo\n";
});
return 0;
}