3

私はPC-Lintの悲しみを引き起こしているブーストコードを理解しようとしていますが、合法的なC ++とは思わなかったが、VS2008では正常にコンパイルされる方法でfriendキーワードを使用しています。

クラスや関数を宣言する方法として友達を理解したと思いました。このような関数定義で使用することは合法だとは思いませんでした。ただし、MSDNページは非常に具体的です。

フレンド関数は、クラス宣言内で定義できます。これらの関数はインライン関数であり、メンバーのインライン関数と同様に、すべてのクラスメンバーが表示された直後で、クラススコープが閉じられる前(クラス宣言の終わり)に定義されたかのように動作します。

クラス宣言内で定義されたフレンド関数は、それを囲むクラスのスコープでは考慮されません。それらはファイルスコープにあります。

ですから、私はそれが異常な構文であるとしても合法であることを理解しています。

友達が何かを宣言する通常の理由は、アクセスを増やすことであるため、何が得られるのかわかりません。ただし、構造体のメンバーはデフォルトですべて公開されているため、ここではそのような利点はありません。

私は何か深遠なものを見逃していますか、それとも誰かが構造体の本体の後にインラインフリー関数を置くのが好きではないというスタイル上のブーストの問題ですか?

_InterlockedIncrementはWin32の組み込み関数であることに注意してください。

# define BOOST_INTERLOCKED_INCREMENT _InterlockedIncrement

struct thread_data_base
{
    long count;
    detail::win32::handle_manager thread_handle;
    detail::win32::handle_manager interruption_handle;
    boost::detail::thread_exit_callback_node* thread_exit_callbacks;
    boost::detail::tss_data_node* tss_data;
    bool interruption_enabled;
    unsigned id;

    thread_data_base():
        count(0),thread_handle(detail::win32::invalid_handle_value),
        interruption_handle(create_anonymous_event(detail::win32::manual_reset_event,detail::win32::event_initially_reset)),
        thread_exit_callbacks(0),tss_data(0),
        interruption_enabled(true),
        id(0)
    {}
    virtual ~thread_data_base()
    {}

    friend void intrusive_ptr_add_ref(thread_data_base * p)
    {
        BOOST_INTERLOCKED_INCREMENT(&p->count);
    }
...
};

アップデート

以下のChubsdadの回答のおかげで、私は今それを理解していると思います。何が起こっているのかについての私の要約です。

  • 彼らはこれらが無料の関数のように振る舞うことを望んでいるので、あなたはただコンパイルすることができますintrusive_ptr_add_ref(somePtrToThreadData)
  • それらが構造体の後に定義されたフリー関数である場合、それらはグローバル名前空間に表示されます
  • フレンド修飾子を使用して構造体内に配置すると、構造体内でスコープが設定されますが、メンバー関数ではないため、静的関数のように動作します。
  • 引数依存のルックアップは、それらがフリー関数であるかのように使用されたときに検出されることを意味します
    • 上記の組み合わせは、それらが自由関数構文を使用する仮想関数であるかのように動作することを意味します(明示的なデータブロックを呼び出されるのではなく、パラメーターとして取得します)
4

2 に答える 2

5

クラス定義内で「フレンド」関数を定義してもまったく問題ありません。この特定のケースでは、フレンド関数は type のパラメーターを取るためthread_data_base、フレンド関数の定義は、クラス定義のレキシカル スコープの外側から呼び出されたときに、ADL (引数依存ルックアップ) $3.4.2 の場合にのみ表示されます。

Herb Sutterの Namespace と Interface Principleを確認してください

于 2010-09-03T01:35:34.463 に答える
1

私は何か深遠なものを見逃していますか、それとも誰かが構造体の本体の後にインラインフリー関数を置くのが好きではないというスタイル上のブーストの問題ですか?

あなたの推測が最も可能性の高い理由のようです。誰かがクラス外の関数を宣言し、関数がクラスに密接に関連しているためにクラス内で宣言を保持したいので、このような難解な構文を使用します。そもそもメンバー関数にするのではなく、なぜこれを行ったのかは誰にも分かりません。

于 2010-09-03T01:14:51.540 に答える