Given the following simple wrapper struct (inspired by this answer):
template <auto* F> struct Wrapper;
template <class Ret, class... Args, auto (*F)(Args...) -> Ret>
struct Wrapper<F>
{
auto operator()(Args... args) const
{
return F(args...);
}
};
The following works:
int this_works(){
return 42;
}
int main(){
return Wrapper<this_works>()();
}
But I want this, using c++ 20:
int main(){
return Wrapper<[](){return 42;}>()();
}
g++-11 --std=c++20 and clang++13 --std=c++20 both complain about the latter
with some hard to decipher error messages, including:
- mismatched types ‘auto*’ and ‘main()::<lambda()>
- error: non-type template parameter ‘F’ with type ‘auto *’ has incompatible initializer
Is there a way to make the second example work? I tried a constexpr function
pointer to the lambda but it complained about it having no linkage …
>Solution :
Wrapper expects function pointer, but template argument deduction won’t consider implicit conversion (from lambda without capture to function pointer).
You can convert the lambda to function pointer explicitly:
int main(){
return Wrapper<static_cast<int(*)()>([](){return 42;})>()();
}
or
int main(){
return Wrapper<+[](){return 42;}>()();
}