Return type match with auto and friend function

So I was answering this question: Define friend function template of class template, and I found some "weird" behavior from g++ (5.3) and clang (3.8):

Let's assume the following template:

template<int M>
struct test {
private:
    int value;

    template<int U, int K>
    friend test<K> foo (test<U> const t);
};

template <int M, int N = 2 * M>
test<N> foo (test<M> const t) {
    test<N> r;
    r.value = t.value;
    return r;
}

int main(){
    test<1> t;
    foo(t);
}

This compile with both compiler (as expected - If this should not compile, feel free to comment and explain why).

If I change things to:

template<int U, int K>
friend auto foo(test<U> const t);

template <int M, int N = 2 * M>
auto foo (test<M> const t) { /* ... */ }

This compile with g++ but not with clang, and if I set one to auto and the other one to a specific value, eg:

template<int U, int K>
friend test<K> foo(test<U> const t);

template <int M, int N = 2 * M>
auto foo (test<M> const t) { /* ... */ }

// or:

template<int U, int K>
friend auto foo(test<U> const t);

template <int M, int N = 2 * M>
test<N> foo (test<M> const t) { /* ... */ }

Both compiler reject the code saying that:

error: 'int test<2>::value' is private

My two related questions are:

  • Which compiler is right for the first case ( auto for both declaration/definition)?
  • Why is not possible to use auto when defining the function and test<K> when declaring the friendship?
  • Or in one question: What are the rules about auto for friend function declarations when the function is defined outside the class?


    Consider [dcl.spec.auto]/13:

    Redeclarations or specializations of a function or function template with a declared return type that uses a placeholder type shall also use that placeholder, not a deduced type.

    Ie if the friend declaration uses auto and the second declaration does not, they don't match. The other way around is guaranteed by core issue 2081. Finally, if both use auto , the declarations should indeed match as per [temp.over.link]/6, so Clang is incorrect in that case.

    链接地址: http://www.djcxy.com/p/92250.html

    上一篇: 分发Haskell应用程序并进行更新的最佳实践

    下一篇: 返回类型与自动和朋友功能匹配