0

std::function<T()>文字列キーをまたはのいずれかにマップする単一のマップが必要std::function<T(int)>です(ただし、特定のキーの両方ではありません)。のテンプレートがないように見えるというコンパイル エラーが発生しますstd::function<T(...)>。ラムダを値として使用できるようにしたいと思います。

まず、この方法で関数を保存しても安全ですか? 第二に、もしそうなら、構文は何ですか? (関数が単項か無項かは、マップから取得したときにわかります。) 上記のいずれでもない場合、合理的な代替手段は何でしょうか? ポインターはラムダのアイデアを殺しますよね…

C++11 は問題ありません。

4

3 に答える 3

5

1つの代替方法は、1つの引数を取り、それに対して何も行わず、ラップされた関数を呼び出すラッパーラムダでnullary関数をラップすることです。そうすれば、マップ内のすべてが単項関数になります。

もちろん、検索時に関数のタイプがわかっている場合(そうしなければならないのではないかと思いますが、そうでなければ役に立たないのです!)、2つのマップを使用しないのはなぜですか?

于 2013-01-04T21:18:41.233 に答える
2

多分試してみboost::variantませんか?

std::map<std::string, boost::variant<std::function<T()>, std::function<T(int)> > >

とにかく、これはXY問題のようです。正確に何をしようとしていますか?

于 2013-01-04T21:18:42.487 に答える
2

std::functionはそれほど重くありません。それぞれの 1 つを含む構造体にマップすることができます。どちらが有効かはわかっているので、その 1 つだけにアクセスしてください。

どちらも引数として渡されずに、両方を均一に操作する必要があるテンプレート コードがある場合:

#include <string>
#include <functional>
#include <map>
#include <tuple>
#include <iostream>
#include <math.h>

template<typename T>
using my_maps = std::tuple< std::map<std::string, std::function<T()>>, std::map<std::string, std::function<T(int)>>>;


int main() {
  my_maps<double> maps;
  std::get<0>(maps)["pi"] = [](){ return 3.14; };
  std::get<1>(maps)["e^"] = [](int x){ return pow( 2.7, x ); };
  std::cout << std::get<1>(maps)["e^"](2) << "\n";
  std::cout << std::get<0>(maps)["pi"]() << "\n";
}

これには 2 つのマップがあり、アクセスの違いは aget<0>または aget<1>です。これには、テンプレートで 2 つのうちどちらにアクセスするかを選択する場合、静的に 0 または 1 を選択して共通コードを使用できるという利点があります。これが必要ない場合は、 を 2 つだけ用意してくださいstd::map

Aboost::variantも機能します ( variant0ary または 1ary 関数の a にマップします)。C++ 11を列挙型 (のコピーを行う) で (union指定しない限り、デフォルトのコンストラクターまたはコピー コンストラクターがないことに注意してください) を使用することもできます。これは基本的に ゲットーです。structunionboost::variant

于 2013-01-04T22:03:22.897 に答える