static constexpr member function in templated using expression not found
Asked Answered
N

1

13

For the following code

#include <array>

template<unsigned MaxP, typename type>
struct kernel
{
  static constexpr unsigned max_pole(unsigned P)
  { return P>MaxP? MaxP:P; }

  template<unsigned P>
  using array = std::array<type,max_pole(P)>;          // wrong?

  template<unsigned P>
  static void do_something(array<P> const&, array<P>&);
};

gcc 4.7.0 (g++ -c -std=c++11) gives

error: ‘max_pole’ was not declared in this scope

Is this correct (behaviour of the compiler)? Note that if I resolve max_pole by replacing it with kernel::max_pole on the line indicated, it compiles fine.

EDIT Reported to bugzilla, accepted as bug c++/55992, see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55992. Also occurs with gcc 4.7.x and 4.8.0.

Nuts answered 15/1, 2013 at 13:31 Comment(1)
Just tested: same for g++ 4.7.2 Someone has a newer version like 4.8? Maybe this is a bug which was fixed...Hoptoad
B
9

Your template compiles fine with Clang 3.2. I strongly believe it is a GCC bug (which is present in GCC 4.7.2 as well, btw). Change notes for GCC 4.8.0 do not seem to mention any such bugfix.

Also notice, that the compilation error disappears if you remove the declaration of do_something<>, which should not make any difference.

One more hint: while this template does not compile on GCC 4.7.2:

template<unsigned MaxP, typename type>
struct kernel
{
    static constexpr unsigned max_pole(unsigned P)
    { return P>MaxP? MaxP:P; }

     template<typename T>
     using array2 = int[max_pole(3)]; // ERROR!

     static void do_something(array2<int> const&, array2<int>&);
};

This template does compile:

template<unsigned MaxP, typename type>
struct kernel
{
    static constexpr unsigned max_pole(unsigned P)
    { return P>MaxP? MaxP:P; }

     // template<typename T>  <--- removed
     using array2 = int[max_pole(3)]; // OK

     static void do_something(array2 const&, array2&);
};

Since max_pole is in both cases an unqualified independent name, the lookup strategy should be the same in both cases, and it is not. To me, this qualifies it as a bug.

Busman answered 15/1, 2013 at 13:39 Comment(4)
So, according to your research, this situation happens specifically when you mix two new C++11 features (constexpr + alias templates) under certain circumstances. The perfect scenario then for a compiler bug.Corrie
@Gorpik: yes, I have the same feelingBusman
@Nuts : Mind posting a link? :-]Marrufo
When you make the constexpr function a template, it fails even in clang 3.2.Involutional

© 2022 - 2024 — McMap. All rights reserved.