2011-11-28 3 views
5

私はこれを持っている場合とし、その後、私が使用して初期化することができますfs関数(または関数オブジェクト)のセットを決定する方法 std :: function <R(T1,T2)>と互換性のある関数型のセットを決定するためのルールはありますか?

std::function<int(int,int)> fs; 

? folllowingの許可とされていません

:もちろん

std::function<int(int,int)> fs = [](int, int) { return int(10); }; 
std::function<int(int,int)> fs = [](char, char) { return char(10); }; 
std::function<int(int,int)> fs = [](int, short) { return int(10); }; 
std::function<int(int,int)> fs = [](double, int) { return float(10); }; 
std::function<int(int,int)> fs = [](int, wchar_t) { return wchar_t(10); }; 

std::function<int(int,int)> fs = [](const char*, int){ return "string"; }; 
std::function<int(int,int)> fs = [](const char*, int){ return 10; }; 
std::function<int(int,int)> fs = [](const char*, int){ return std::string(); }; 

、私はコンパイルして罰金コンパイルどれ見ることができる、としません。しかし、それはパラメータのタイプと戻り値の型の違いを理解するのに役立ちません。どのように私はそれらのために異なるタイプを使用するために行くことができますか?

つまり、関数(または関数オブジェクト)を与えても、std::function<int(int,int)>と互換性があるかどうかをコンパイル時にどのように判断できますか?私はほとんど理解していないが、私は十分自信がない。

std::function<R(T1,T2)>と互換性のある関数タイプのセットを決定するためのルールを理解し、レイアウトするのを手伝ってください。メタプログラミングは、互換性のない機能を使用する場合、ユーザーに通知し、素晴らしいエラーメッセージを生成するのに役立ちますか?ところで、第一のグループは互換性があるように思われる

http://ideone.com/hJpG3

答えて

4

オブジェクト(関数ポインタまたはファンクタ)指定された引数の型を持つ呼び出し可能でなければならない、即ちfun(declval<Types>() ...)はよく形成され、Rに暗黙的に変換可能です。

特にC++ 11§20.8.2を参照してください。それはポインタへのポインタなど様々な特殊なケースを与える.20.8.11.2/2と20.8.11.2.1/7はこれをstd::functionコンストラクタに結びつける。

4

事前にパッケージ化されたメタプログラミングソリューションはありません。私はこの質問を助けるために次のような特性をプログラムしました。これらの特性はPotatoswatterの答えに言及されたセクションを単に実装するだけです。コードコメントは、参照セクションの箇条書きポイントも列挙します。

template <class _F, class ..._Args> struct __invokable; 
template <class _F, class ..._Args> struct __invoke_of; 

http://llvm.org/svn/llvm-project/libcxx/trunk/include/type_traits

私はstd::functionのプライベート "メンバーの特性" を作成するためにこれらを使用しました:

template <class _F, bool = __invokable<_F&, _ArgTypes...>::value> 
    struct __callable; 

http://llvm.org/svn/llvm-project/libcxx/trunk/include/functional

これらが良いになるかもしれないことを私に発生しましたtr2素材(先頭のアンダースコアを除く)。あなたが同意するならば、あなたはおそらくあなたの国家代表者に知らせるべきです。

これらの形質を使用したい場合、コードはオープンソースです。しかし、各ファイルに著作権情報を含めることでオープンソースライセンスを尊重していただければ幸いです。

+0

この回答は標準ライブラリによって公開されている機能の文脈のようです...私の答えが間違っている場合は、その理由についてコメントできますか?編集 - この特性は戻り値の変換を無視しているようです... – Potatoswatter

+0

@Potatoswatter:これらの特性の実装を見直しました。それらは 'std :: forward'、' std :: is_convertible'、 'std :: is_same'に依存しています。それらはstd :: libの一部として実装できます。私は私の答えを見直して、あなたの答えが間違っていることを暗示している場所を見ていない。私の答えは、あなたが参照するセクションのメタプログラミング実装を提供するだけです。 OPは、メタプログラミングのソリューションについて尋ねたので、私は答えが適切であると思った。戻り値の変換について:これは '__invoke_of'と' is_convertible'を使って '__callable'でカバーしています。 –

+1

よろしいですか。唯一の意見の不一致は、私の回答が「あらかじめパッケージ化された標準的な回答」であると考えていることです。戻り値の型変換に関して、私はリンクをたどらず、希望の戻り値型にアクセスすることができない非メンバのテンプレートであると仮定しました。ユーザーレベルでは、 'std :: is_convertible :: type、R> :: value'では十分ではありませんか?私はあなたがSFINAEか「偽」の結果を望むかどうかにかかっていると思います。 – Potatoswatter

関連する問題