Reputation: 10243
I'm using the solution proposed in this answer to get the arguments from a lambda function and it's working fine when the number of parameters is fixed. I first created a variant with one argument and would like to add a second one which accepts two arguments. I'm not looking to generalize this, just the two options below.
class MyClass {
template<typename Lambda>
typename std::enable_if<function_traits<Lambda>::arity, 1>>
void Each(Lambda lambda) {
using Traits = function_traits<decltype(lambda)>;
using Arg0 = typename Traits::template arg<0>::type;
lambda(Conv<Arg0>().ToType(this));
}
template<typename Lambda>
typename std::enable_if<function_traits<Lambda>::arity, 2>>
void Each(Lambda lambda) {
using Traits = function_traits<decltype(lambda)>;
using Arg0 = typename Traits::template arg<0>::type;
using Arg1 = typename Traits::template arg<1>::type;
lambda(Conv<Arg0>().ToType(this), Conv<Arg1>().ToType(this));
}
}
void main() {
MyClass myClass;
myClass.Each([](int arg) {});
myClass.Each([](int arg0, int arg1) {});
}
This code, of course, doesn't compile at all but I still don't understand how enable_if works well. I'm using GCC 6.2.0 so can't use C++17 features like if constexpr, otherwise I'd be using that. What does the correct implementation look like here?
Upvotes: 1
Views: 97
Reputation: 1173
Assuming Conv
is defined
class MyClass {
public:
template<typename Lambda>
typename std::enable_if<(function_traits<Lambda>::arity == 1), void>::type
Each(Lambda lambda) {
using Traits = function_traits<decltype(lambda)>;
using Arg0 = typename Traits::template arg<0>::type;
lambda(Conv<Arg0>().ToType(this));
}
template<typename Lambda>
typename std::enable_if<(function_traits<Lambda>::arity == 2), void>::type
Each(Lambda lambda) {
using Traits = function_traits<decltype(lambda)>;
using Arg0 = typename Traits::template arg<0>::type;
using Arg1 = typename Traits::template arg<1>::type;
lambda(Conv<Arg0>().ToType(this), Conv<Arg1>().ToType(this));
}
};
int main() {
MyClass myClass;
myClass.Each([](int arg) {});
myClass.Each([](int arg0, int arg1) {});
return 0;
}
Upvotes: 1