24

デフォルトの引数を指定せずにデフォルトの引数を取る関数にバインドして、引数なしで呼び出すにはどうすればよいですか?

void foo(int a, int b = 23) {
  std::cout << a << " " << b << std::endl;
}

int main() {
  auto f = std::bind(foo, 23, 34); // works
  f();


  auto g = std::bind(foo, 23); // doesn't work
  g();

  using std::placeholders::_1;
  auto h = std::bind(foo, 23, _1); // doesn't work either 
  h();

}
4

4 に答える 4

29

基本的に、コンパイラを作成するたびにfoo(x)、コンパイラはそれをに変換しfoo(x, 23);ます。これは、実際に関数名を使用して直接呼び出す場合にのみ機能します。たとえば、関数のシグネチャは。であるため、に割り当てる&fooことはできません。デフォルトのパラメータは署名には関与しません。また、それを変数に割り当てると、デフォルトのパラメーターに関する情報が失われます。その変数を介してデフォルトのパラメーターを利用することはできません。腸のどこかに格納されるため、デフォルトのパラメータ情報が失われます。void(*)(int)void(int, int)void(*)(int, int)std::bindvoid(*)(int, int)

C ++には、関数の外部からパラメーターのデフォルト値を取得する方法がないため、バインド時にデフォルト値を手動で指定する必要があります。

于 2012-05-23T11:40:10.643 に答える
10

ラムダを使用して、必要な動作をシミュレートできると思います。

これに沿った何か:

auto g = [] (){ foo( 23 ); };

編集:チェックしたばかりで、正常に動作しているようです:http: //ideone.com/SPSvi

于 2012-05-23T11:44:05.017 に答える
2

私には2つの解決策があります:

1-foo()をオーバーロードして、デフォルトで元のファイルを呼び出すことができます。

void foo(int a, int b) 
{
    std::cout << a << " " << b << std::endl;
}

inline void foo(int a)
{
    foo(a, 23);
}

2-静的変数をデフォルトとして使用し、それをバインディングプロセスで使用できます。

static int foo_default_b = 23;
void foo(int a, int b = foo_default_b) 
{
    std::cout << a << " " << b << std::endl;
}

auto g = std::bind(foo, 23, foo_default_b);
g();
于 2012-05-23T11:51:51.787 に答える
-4

この答えは、R。MartinhoFernandesの答えとは一致しません。確かboost::bindに、デフォルトのパラメーターにバインドするために使用できます。プレースホルダーを挿入するだけで、次のようになります。

boost::bind<void (int, int)>(foo, _1, _2)(12);

予想どおり、これはを呼び出しますfoo(12, 23)。この特定のコードはテストしていませんが、上記のリンクに基づいてコードで同様のことを行いました。これはで機能しgcc 4.8.5ます。

std::bindうーん、私はこれがではなく、について尋ねていることに気づきましたboost::bind。違いがあるかどうかはわかりません。

于 2015-12-23T14:00:40.947 に答える