Error with using decltype() in C++11 (creating opaque error message in gcc 4.7.0)

后端 未结 5 2492
别那么骄傲
别那么骄傲 2021-02-19 09:55

with the following code (a boiled-down version of my original code)

#include 
#include 

template  class A;                   


        
5条回答
  •  旧巷少年郎
    2021-02-19 10:47

    TL;DR: Gcc appears to have a bug where trailing return types on template member functions are not treated as within the class's scope.

    This bug causes gcc to fail when instantiating the template member function auto diff(A const&y) const -> decltype(a-y.a) because a is private and gcc thinks private members are inaccessible here.


    The code builds fine with clang and VC++, and I don't see anything trying to access A::a outside A, so it looks like a gcc bug to me.

    Others have mentioned that A and A are different classes, but that's not the case here, both are A. I believe that means that friendship is not necessary in this case, although to work in the general case A does need to be friends with other specializations of A.

    Specifically, a in y.a is a dependent name so it cannot be looked up until A is known. At that point lookup is done, the accessibility is tested and it should be found that A does have access to A::a.

    Here's the exact code I compiled in both clang (svn-3.2) and VC++11 (Since I'm using clang on Windows I can't #include )

    #include 
    
    template class A {
      X a;
    public:
      A(X x) : a(x) {}
      template
      auto diff(A const&y) const -> decltype(a-y.a)
      { return a-y.a; }
    };
    
    template
    inline auto dist(A const&x, A const&y) -> decltype(std::abs(x.diff(y)))
    { return std::abs(x.diff(y)); }
    
    int main()
    {
      A x(2.0), y(4.5);
      return (int) dist(x,y);
    }
    

    This code results in build errors on gcc 4.5 similar to what you describe.

    Replacing

    auto diff(A const&y) const -> decltype(a-y.a)
    

    with

    auto diff(A const&y) const -> typename std::common_type::type
    

    causes the code to work on gcc 4.5.

    This indicates to me a bug where gcc is failing to treat trailing return types as inside the class's scope. Some testing reveals that the trailing return type must be on a template function to trigger the bug.

提交回复
热议问题