簡體   English   中英

隱藏的朋友:聲明和定義

[英]Hidden friends: declarations and definitions

在他最近的博客文章中,安東尼威廉姆斯談到了隱藏的朋友。 如果我理解正確的話,主要思想是在某些情況下 ADL 無法找到聲明為友元的函數。 簡單的例子:

namespace N {
    struct A {
        friend void foo(A) { }
    };

    struct B {
        operator A();
    };

    // (*)
    void bar(A) { }
}

void func() {
    N::A a;
    bar(a);   // OK, bar is found via ADL
    foo(a);   // OK, foo is found via ADL

    N::B b;
    bar(b);   // OK, bar is found via ADL
    foo(b);   // NOT OK, foo cannot be found
}

在博客文章中的所有示例中,友元函數都是在類中定義的。 是否可以聲明一個友元函數,然后稍后在(*)點定義它,使其保持隱藏狀態? 看起來隱藏的朋友只能在類范圍內(或在另一個編譯單元中)定義。

隱藏的朋友需要完全內聯定義,即在類定義的內部。 是的,如果您在其他地方定義友元,其中定義會導致命名空間可見性,它會打破基於隱藏友元的限制,僅通過 ADL 搜索才能找到匹配項,因此成為重載解析的候選者。

WG21指定隱藏好友的更多建議中,注意到隱藏好友是完全內聯定義的,就像在這個片段中一樣:

#include <ostream>
#include <compare>
class C  {
    friend ostream& operator << ( ostream&, C const& )  {}
    friend auto   operator <=>( C const&, C const& )  = default;
};

隱藏的朋友可以被定義為不合時宜,但他們不會隱藏在那個 TU 中。 例如,請考慮以下標頭:

class A {
    // this is hidden friend defined inline
    friend int operator+(A, int) { return 0; }
    // this is hidden friend defined out of line
    friend int operator+(int, A);
    // not a hidden friend (see below)
    friend int operator+(A, A);
};
int operator+(A, A); // this is no longer hidden friend in any TU

然后是一個單獨的 cpp 文件:

#include "a.hpp"

// This is not a hidden friend in this TU, but is in other TUs.
int A::operator+(int, A) {
    return 2;
}

當您的操作符/ADL 自定義點依賴於其他大型頭文件的實現時,這樣做很有用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM