Interesting question raised in stackoverflow about non-deduced context usage for deduced type for function.
Explained inline:
#include <iostream>
#include <functional>
#include <type_traits>
using namespace std;
/**
* foo shall fail due to TArgs's first 2 specialized argument are;
* in our example below in main, (int, int);
* however, the deduce of packing continues from the argument in case needs to be extended;
* thus TArgs is deduced to empty pack(because [](int,int){} has both int args matched),
* and std::function<void(empty)> can not take [](int,int){};
*/
template <typename... TArgs>
void foo(std::function<void(TArgs...)> f) {
}
/**
* Non-deduced contexts compes into the play.
* https://vsdmars.blogspot.com/2022/07/c20-stdtypeidentity-for-non-deduced.html
* Type inside std::type_identity_t<...> is replaced not deduced.
*/
template <typename... TArgs>
void foo_cure(std::type_identity_t<std::function<void(TArgs...)>> f) {
}
int main() {
// foo<int,int>([](int, int){}); // no can do.
foo_cure<int,int>([](int, int){});
}
code in action:
https://godbolt.org/z/qrG5G53ar
There are other ways around for OP's question, e.g. using class template with static member function
taking the specialized class template arguments for the static member function; or, simply,
use universal reference template for the standalone template function taking the lambda expression object with variable argument-types.
Alas, while start coding in Rust, C++ makes me feel taking more time ruminating for the better solution than solving the problem, kinda like Perl?! In the long run I bet Rust shall take over; however, template programming is fun. 😄
Further read:
[C++20] std::type_identity for Non-deduced contexts
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.