6

関数呼び出しであるデフォルトのパラメーターを使用して C / C++ 関数ヘッダーを記述するための良い方法はありますか?

関数を含むヘッダーがあります:

int foo(int x, int y = 0);

多くの関数がこの関数を呼び出し、このデフォルト値に依存する大規模なコード ベースで作業しています。このデフォルト値を動的なものに変更する必要があり、その方法を探しています:

int foo(int x, int y = bar());

bar() は、いくつかのシステム パラメータに基づいてデフォルト値を生成する関数です。あるいは、この関数プロトタイプは次のようになります。

int foo(int x, int y = baz.bar());

baz は、ヘッダー ファイル内でインスタンス化されていないオブジェクトに属する関数です。

4

8 に答える 8

7

2 つのオーバーロードされた関数を使用します。

int foo(int x, int y);

int foo(int x){return foo(x,bar);}

フォワーディング関数をインライン化できるようにすると、パフォーマンスの低下はほとんどゼロになります。ヘッダー以外のファイルでその本体を行外に保持すると、パフォーマンス コストが発生する可能性がありますが (小さい可能性があります)、実装の柔軟性が大幅に向上し、結合が減少します。

于 2008-10-14T20:52:38.327 に答える
7

図に行く!それは機能します。C++ 関数のデフォルト引数

于 2008-10-14T20:48:11.707 に答える
6

最初の宣言で省略可能なパラメーターを単純に削除し、単一のパラメーター オーバーロードを提供することの何が問題になっていますか?

int foo(int x)
{
    Bar bar = //whatever initialization
    return foo(x,bar.baz());
}

int foo(int x,int y)
{
  //whatever the implementation is right now
}

これは、動的なデフォルト値を使用しようとするよりも、はるかにクリーンで柔軟になる傾向があると思います。

于 2008-10-14T20:52:44.833 に答える
6

はい。あなたが書いたものは機能します。

于 2008-10-14T20:47:20.180 に答える
4

標準のセクション 8.3.6 (デフォルト引数) のパラグラフ 5 では、このアプローチだけを使用した例が示されています。具体的には、デフォルトの引数がexpressionであることを示しているため、関数呼び出しが適用されますが、名前の検索や型の互換性などの制限があります。

私の職場では、次のような署名を使用しています。

void An_object::An_object(
  const Foo &a,
  const Bar &b,
  const Strategem &s = Default_strategem()
);

クライアントがクラス コンストラクターの動作をオーバーライドできるようにします。トランスレータのパフォーマンスに影響を与える条件付き動作に役立ちました...

于 2008-10-14T23:48:57.893 に答える
2

接線的ですが、それは将来的に依存関係の問題を引き起こすように私には見えます。私はstbuton.myopenid.comのアプローチを採用します。

于 2008-10-14T21:32:07.280 に答える
1

関数/オブジェクトの宣言がスコープ内にある限り、このコンテキストでグローバル関数を呼び出したり、グローバル オブジェクトを参照したりすることは完全に有効です。(優れた設計の観点から)お勧めかもしれませんし、そうでないかもしれませんが、うまくいくはずです。

于 2008-10-14T20:48:50.910 に答える
0

bar() を静的メンバー関数にしてみてください。これにより、スコープ内にそのような静的クラスを持つプログラムの任意の部分がそれにアクセスできるようになります。例えば:

クラス Foo { public:

static int bar(); };

次に、次のように宣言します。

int foo(int x, int y = Foo::bar());

別のオブジェクトが必要な場合は、代わりにオブジェクトのインスタンスを渡します。

于 2008-10-14T20:53:46.000 に答える