...A lambda-expression shall not appear in an unevaluated operand...
I was going to give up on keeping the function calls inside decltype() (one of my replies to his thread), but then I noticed that I placed my lambda directly in the decltype(). It worked once I moved the lambda into a function; this is the result.
Correction to my previous post (thanks to KrzaQ2 on reddit): these examples rely on C++1y; C++11 doesn't have auto return type deduction for functions.
First some boilerplate from my previous post...
#include <assert.h> #include <iostream> #include <type_traits> #include <typeinfo> using namespace std; template<class T> struct Type { using type = T; }; template<class T> auto ptr(Type<T>) { return Type<T*>{}; } template<int i> using int_ = integral_constant<int, i>; #define EXTRACT_TYPE(e) decltype(e)::type #define ASSERT_EXTRACT_TYPE(a, b) \ assert(typeid(EXTRACT_TYPE(a)) == typeid(b))loopn composes a functor to itself n times. I test it by passing in a generic lambda.
// Loop 0 times: don't call F template<class Arg, class F> auto loopn(int_<0>, Arg arg, F) { return arg; } // Loop n times template<int n, class Arg, class F> auto loopn(int_<n>, Arg arg, F f) { return loopn(int_<n-1>{}, f(arg), f); } // Convenience wrapper template<int n, class Arg, class F> auto loopn(Arg arg, F f) { return loopn(int_<n>{}, arg, f); } // exampleLoop<n>() produces an int****... template<int n> auto exampleLoop() { return loopn<n>( Type<int>{}, [](auto arg){return ptr(arg);}); } void testLoopn() { // This doesn't work because of N3797 5.1.2/2: // ...A lambda-expression shall not appear // in an unevaluated operand... // ASSERT_EXTRACT_TYPE( // loopn<2>( // Type<int>{}, // [](auto arg){return ptr(arg);}), // int**); ASSERT_EXTRACT_TYPE(exampleLoop<0>(), int); ASSERT_EXTRACT_TYPE(exampleLoop<1>(), int*); ASSERT_EXTRACT_TYPE(exampleLoop<2>(), int**); ASSERT_EXTRACT_TYPE(exampleLoop<10>(), int**********); // Stress test; we're getting close to the default template // nesting depth limits in clang and Visual C++ Nov // 2013 CTP. decltype(exampleLoop<200>())::type p{}; } int main() { testLoopn(); cout << "Tests passed" << endl; }
No comments:
Post a Comment