返回类型匹配auto和friend功能

Hol*_*olt 7 c++ friend language-lawyer auto c++14

所以我回答了这个问题:定义类模板的友元函数模板,我从g ++(5.3)和clang(3.8)中发现了一些"怪异"的行为:

我们假设以下模板:

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);
}
Run Code Online (Sandbox Code Playgroud)

这与两个编译器一起编译(如预期的那样 - 如果这不应该编译,请随意发表评论并解释原因).

如果我改变了:

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) { /* ... */ }
Run Code Online (Sandbox Code Playgroud)

这用g ++编译但不用clang编译,如果我设置一个auto而另一个设置为特定值,例如:

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) { /* ... */ }
Run Code Online (Sandbox Code Playgroud)

两个编译器拒绝代码说:

错误:'int test <2> :: value'是私有的

我的两个相关问题是:

  • 哪种编译器适用于第一种情况(auto对于声明/定义)?
  • 为什么auto在定义函数和test<K>声明友谊时无法使用?

或者在一个问题中:当在类外部定义函数时,有关auto友元函数声明的规则是什么?

Col*_*mbo 4

考虑[dcl.spec.auto]/13

具有使用占位符类型的声明返回类型的函数或函数模板的重新声明或特化也应使用该占位符,而不是推导类型。

即,如果朋友声明使用auto而第二个声明没有使用,则它们不匹配。核心问题 2081保证了相反的方式。最后,如果两者都使用auto,则声明确实应该按照[temp.over.link]/6匹配,因此在这种情况下 Clang 是不正确的。