返回类型与自动和朋友功能匹配

时间:2016-06-17 13:14:55

标签: c++ c++14 language-lawyer friend auto

所以我回答了这个问题: Define friend function template of class template ,我找到了一些"怪异的"来自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);
}

使用两个编译器进行编译(如预期的那样 - 如果不能编译,请随意发表评论并解释原因)。

如果我将事情改为:

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) { /* ... */ }

使用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) { /* ... */ }

两个编译器都拒绝代码说:

  

错误:&#39; int test&lt; 2&gt; :: value&#39;是私人的

我的两个相关问题是:

  • 哪种编译器适用于第一种情况(声明/定义auto)?
  • 为何在定义功能时无法使用auto,在宣布友谊时使用test<K>

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

1 个答案:

答案 0 :(得分:4)

考虑[dcl.spec.auto]/13

  

功能或功能模板的重新声明或特化   使用占位符类型的声明返回类型也应该   使用该占位符,而不是推断类型。

即。如果朋友声明使用auto而第二声明不使用,则他们不匹配。另一种方法是由core issue 2081保证。最后,如果两者都使用auto,则声明应该按照[temp.over.link]/6匹配,因此在这种情况下Clang不正确。