【问题标题】:Should a friend function of a class template become friend to all instantiations?类模板的友元函数是否应该成为所有实例化的友元?
【发布时间】:2020-08-20 18:22:42
【问题描述】:

考虑以下 sn-p:

template<typename T> struct Foo {
    friend void bar(Foo, Foo<char> f) {
        static_cast<void>(f.private_field);  // Should only compile when friends with Foo<char>.
    }
private:
    int private_field{};
};

int main() {
    bar(Foo<char>{}, Foo<char>{});  // Compiles.
    bar(Foo<bool>{}, Foo<char>{});  // Compiles erroneously?
}

它可以使用 trunk(截至 2020 年 5 月 6 日)GCC 成功编译,但不能使用 Clang 和 MSVC:请参阅 Godbolt

谁在这里?

来自 Clang 和 MSVC 的错误消息与预期一致:

<source>:3:29: error: 'private_field' is a private member of 'Foo<char>'

        static_cast<void>(f.private_field);  // Should only compile when friends with Foo<char>.

                            ^

<source>:11:5: note: in instantiation of member function 'bar' requested here

    bar(Foo<bool>{}, Foo<char>{});  // Compiles erroneously?

    ^

<source>:6:9: note: declared private here

    int private_field{};

        ^

1 error generated.

Compiler returned: 1

example.cpp

<source>(3): error C2248: 'Foo<char>::private_field': cannot access private member declared in class 'Foo<char>'

<source>(6): note: see declaration of 'Foo<char>::private_field'

<source>(2): note: see declaration of 'Foo<char>'

<source>(2): note: while compiling class template member function 'void bar(Foo<bool>,Foo<char>)'

<source>(11): note: see reference to function template instantiation 'void bar(Foo<bool>,Foo<char>)' being compiled

<source>(11): note: see reference to class template instantiation 'Foo<bool>' being compiled

Compiler returned: 2

【问题讨论】:

    标签: c++ templates language-lawyer friend-function


    【解决方案1】:

    GCC 在这里显然是错误的:因为每个特化都定义了自己单独的友元函数(必须避免重复定义错误),bar(Foo&lt;char&gt;,Foo&lt;char&gt;)Foo&lt;char&gt; 的友元,但bar(Foo&lt;char&gt;,Foo&lt;char&gt;) 不是。该标准包含一个相关的example,其中提到了一个非常相似的案例。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-22
      • 2011-07-15
      • 1970-01-01
      • 2010-12-19
      • 1970-01-01
      相关资源
      最近更新 更多