9

boost::function FAQ 項目 3は、私が興味を持っているシナリオに具体的に対応しています。

void リターンの回避策があるのはなぜですか? C++ はそれらを許可します! 次のコード スニペットのように、C++ 標準では void リターンが許可されています。

void f();
void g() { return f(); }

void リターンが使用されないため、これは boost::function の有効な使用法です。void を返すと、次のような形式の悪いコードをコンパイルしようとします。

int f();
void g() { return f(); }

本質的に、void リターンを使用しないと、boost::function が戻り値を飲み込むことができます。これは、正確に一致しないパラメータを持つ関数と関数オブジェクトをユーザーが割り当てて呼び出すことを許可することと一致しています。

残念ながら、これは VS2008 では機能しません:

int Foo();
std::tr1::function<void()> Bar = Foo;

これにより、次のエラーが発生します。

c:\Program Files\Microsoft Visual Studio 9.0\VC\include\xxcallfun(7) : error C2562: 'std::tr1::_Callable_fun<_Ty>::_ApplyX' : 'void' function returning a value

これは VS2008 TR1 実装の失敗ですか? これはVS2010で動作しますか? TR1 はこの機能に対応していますか? C++0x はどうですか?

4

1 に答える 1

8

tr1 がこの問題に対処していると思います。 N1836 (最新の tr1 ドラフト) は次のように述べています。

型 F の関数オブジェクト f は、左辺値 t1、t2、...、tNoftypesT1、T2、...、TN がそれぞれ与えられる場合、引数の型 T1、T2、...、TN および戻り値の型 R に対して Callable です。 ,INVOKE(f, t1, t2, ..., tN) は整形式 ([3.3]) であり、R が void でない場合、R に変換可能です。

あなたの例では R は無効であるため、Callable(R に変換可能) の要件の最後の部分は無視されます。

ただし、C++0x (C++11) ではルールが変更されているようです。C++11 では、[func.require] で定義されているように定義されており、R が void の場合は例外なく、暗黙的に R に変換可能である必要Callableがあります。したがって、C++11 では、例は失敗するはずです。INVOKE(f, t1, t2, ..., tN, R)INVOKE(f, t1, t2, ..., tN)

于 2011-07-08T19:09:45.570 に答える