Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Name lookup for local class members inside templates

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?

like image 480
TemplateRex Avatar asked Jun 13 '15 14:06

TemplateRex


People also ask

How does lookup work for a name used outside the namespace?

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:

Is the scope of a base class determined by the template parameter?

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

What is a template-parameter name?

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.

What are dependent names and non-dependent names inside templates?

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.


1 Answers

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.

like image 79
TemplateRex Avatar answered Sep 27 '22 22:09

TemplateRex