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

所以我回答了这个问题:定义了类模板的朋友函数模板,并且发现了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) { /* ... */ }

两个编译器都拒绝这样的代码:

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

我的两个相关问题是:

  • 哪种编译器适用于第一种情况( auto适用于声明/定义)?
  • 为什么在定义函数时不可能使用auto ,并且在声明友谊时test<K>
  • 或者在一个问题中: 当函数在类外部定义时,有关auto的朋友函数声明的规则是什么?


    考虑[dcl.spec.auto] / 13:

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

    也就是说,如果朋友声明使用auto ,而第二声明不使用,则它们不匹配。 另一种方式是由核心问题2081保证。最后,如果两者都使用auto ,则声明的确应与[temp.over.link] / 6匹配,所以在这种情况下Clang是不正确的。

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

    上一篇: Return type match with auto and friend function

    下一篇: Why does stringstream not move to next set of characters when cout?