I am attempting to make a function that helps handling N std::variant types.
Note: I am trying to make all pathways compile time validated. So std::optional and std::holds_alternative are not viable for me.
The implementation is as follows:
template<typename T>
using Possible = std::variant<std::monostate, T>;
template<typename... Types>
void ifAll(std::function<void(Types...)> all, Possible<Types>&&... possibles)
{
std::visit(
[&](auto&&... args) {
if constexpr ((... &&
std::is_same_v<std::decay_t<decltype(args)>, Types>))
{
return all(std::forward<Types>(args)...);
}
else
{
std::cout << "At least one type is monostate" << std::endl;
}
},
possibles...);
}
And an example of using the function is:
int main()
{
Possible<int> a = 16;
Possible<bool> b = true;
ifAll([](const int& x, const bool& y)
-> void { std::cout << "All types set!" << std::endl; },
a,
b);
}
However I get a compiler error:
TestFile.cc: error: no matching function for call to 'ifAll'
ifAll([](const int& x, const bool& y)
^~~~~
TestFile.cc: note: candidate template ignored: could not match
'function<void (type-parameter-0-0...)>' against '(lambda at
TestFile.cc)'
void ifAll(std::function<void(Types...)> all, Possible<Types>&&... possibles)
^
Why does the lambda I provide not match the function signature?
Attempted Fix 1
I tried moving in a and b which still does not work:
ifAll([](const int& x, const bool& y)
-> void { std::cout << "All types set!" << std::endl; },
std::move(a),
std::move(b));