...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