Consider the following code, that simulates a constexpr
lambda (proposed for C++17, not available in C++14).
#include <iostream>
template<int M, class Pred>
constexpr auto fun(Pred pred)
{
return pred(1) <= M;
}
template<int M>
struct C
{
template<int N>
static constexpr auto pred(int x) noexcept
{
// simulate a constexpr lambda (not allowed in C++14)
struct lambda
{
int n_, x_;
constexpr auto operator()(int y) const noexcept
{
return this->n_ * this->x_ + y;
// ^^^^ ^^^^ <---- here
}
};
return fun<M>(lambda{N, x});
}
};
int main()
{
constexpr auto res = C<7>::template pred<2>(3);
std::cout << res; // prints 1, since 2 * 3 + 1 <= 7;
}
Here, the lambda
is defined inside a function template member of a class template. Surprisingly, I have to this->
ambiguate the lambda
member variables n_
and x_
.
Live examples (with this->
, without this->
)
I was under the impression that this is only necessary in dependent base classes, but the lambda
class is just a local class, not a dependent base class.
Question: can someone point me to the relevant Standardese for name lookup of local class members inside templates?
For a name used in the definition of a namespace-member variable outside the namespace, lookup proceeds the same way as for a name used inside the namespace:
In any case, if a base class depends on a template parameter, its scope is not examined by unqualified name lookup (neither at the point of definition nor at the point of instantiation).
A name used in a template declaration or definition and that is dependent on a template-parameter is assumed not to name a type unless the applicable name lookup finds a type name or the name is qualified by the keyword typename.
Names inside templates are divided to two types: Dependent - names that depend on the template parameters but aren't declared within the template. Non-dependent - names that don't depend on the template parameters, plus the name of the template itself and names declared within it.
Thanks to the comment of @dyp, it appears to be a bug in Clang 3.5 / 3.6 that is fixed in Clang 3.7 tip of trunk. G++ 4.8.1 through tip of trunk compile this correctly as well.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With