5

ある(コンパイル時の)条件が真の場合にのみ、フレンドクラスを宣言したい。例えば:

// pseudo-C++
class Foo {
    if(some_compile_time_condition) {
        friend class Bar;
    }
};

インターネット上で解決策は見つかりませんでした。コンパイル時に構造を動的に生成するという質問に対するすべての回答を調べました。それらの多くはC++11を使用していますが、プリプロセッサを使用せずstd::conditionalにC++03でこれを実行できるかどうかを知りたいと思います。

このソリューションhttps://stackoverflow.com/a/11376710/252576friendは、 shipが継承されていないため機能しません(継承されたフレンドクラス)。

以下のコメントで説明されているように、これをより見やすくするために編集してください。この要件は珍しいものです。これは、私が取り組んでいるハードウェアシミュレーションの新しい研究プロジェクトの一部です。テストベンチはC++で記述されており、変数を波形で表示したいと思います。私は他のさまざまなオプションを調査しましたが、friend class実際的な考慮事項から、を使用する必要があることがわかりました。友人は値をキャプチャして波形を生成しますが、波形が必要な場合にのみ友人がいることを望みます。常にではありません。

4

5 に答える 5

6

friend std::conditional<C, friendclass, void>::type;あなたの状態がどこにあるかを使用しCてください。非クラス型のフレンドは無視されます。

条件付きテンプレートは、C++03 で簡単に実装できます。ただし、C++03 は typedef フレンドをサポートしていないため、次の構文を使用する必要があります。

namespace detail { class friendclass {}; }

class Foo {
  friend class std::conditional<C, 
    friendclass, detail::friendclass>::type::friendclass;
};

詳細ダミー クラス名は、この回避策の潜在的な友人の名前と一致する必要があることに注意してください。

于 2012-12-21T08:51:46.420 に答える
2

[class.friend] / 3はこれを伝えます:

関数を宣言しないfriend宣言は、次のいずれかの形式になります
。friend elaborated-type-specifier;
フレンドsimple-type-specifier;
フレンドtypename-specifier;

したがって、マクロがないと、クラスの友達を条件付きで宣言することはできません。

于 2012-12-21T07:03:23.667 に答える
2

残念ながら、C++ コンパイラ内では不可能のようです。つまり、プリプロセッサだけがここで役立つようです注: Johannes から提案があるので、希望があります!

ただし、次のことに注意してください。

  • 友情は実際にそれを使用する必要はありません
  • 友情は純粋なコンパイル時の構成要素 (アクセス指定子など) であり、主要なコンパイラで実行時のペナルティは発生しません。

無条件の友情を持たない理由はありませんが、いくつかの条件 (静的または動的) が満たされた場合にのみ使用してください。

注: 将来的には、これは static_if 提案でカバーされる可能性があります。

于 2012-12-21T07:35:52.780 に答える
0

注: Johannesはほぼ完璧です。'03 では、typedef とフレンドになることはできませんが、クラスがあることがわかっている場合は、それを参照できますinjected class name

ヨハネスの答えには、標準ライブラリ機能を使用するという利点もありますが、これも常に良いことです。

#define some_compile_time_condition 0

class Foo;

template <int Condition> class  TestCondition {
private:
  friend class Foo;
  struct Type {
    struct Bar;
  };
};

template <> class TestCondition<1> {
public:
  typedef Bar Type;
};

struct Bar
{
public:
  void foo (Foo &);
};

class Foo {
private:
  friend struct TestCondition< some_compile_time_condition >::Type::Bar;
  int m_i;
};

void Bar::foo (Foo & foo)
{
  foo.m_i = 0;
}

常にフレンドがいるという要件とは異なりますFooが、フレンドになるクラスはオプションの値に基づいて変化します。

興味深い副次的な質問は、1 に設定されたバージョンと設定されていないバージョンのFoo両方を持つことが ODR 違反であるかどうかsome_compile_time_condition です。

于 2012-12-21T08:54:00.087 に答える
0

プリプロセッサを 1 つ取り、その中にソース コードを記述していると思います。

bool flag = false;
#ifdef _MY_FRIEND_
    friend class sample
    flag = true;
#endif

if (flag)
{
 ...
 ...
 ...
}

class Foo {
#ifdef _MY_FRIEND_
    friend class Bar;
#endif
}

};

ここで _MY_FRIEND_ はプリプロセッサであり、そのプリプロセッサを追加すると、コンパイル時にクラス Bar がフレンド クラスになります...クラス Bar がフレンド クラスとして必要な場合は、どこでもそのプリプロセッサを使用できます。プリプロセッサの場合、Bar を Foo のフレンド クラスとして追加することはできません

私が質問を間違って理解した場合は、私を修正してください。

于 2012-12-21T12:11:28.233 に答える