10

よく聞かれる「オーバーロードされた関数へのポインターを指定するにはどうすればよいですか?」に対する答えを知っています。:代入またはキャストのいずれかを使用し、他のすべての C++ チュートリアルでは、次のように文字列を大文字にします (ギブまたはテイクstatic_cast):

transform(in.begin(), in.end(), back_inserter(out), (int(*)(int)) std::toupper);

またはこのように:

int (*fp)(int) = std::toupper;
transform(in.begin(), in.end(), back_inserter(out), fp);

<cctype>のオーバーロードをきちんと選択しstd::toupperます。

しかし、ここで疑問が生じます<locale>。同様の方法でオーバーロードを選択するにはどうすればよいでしょうか?

char (*fp2)(char, const std::locale&) = std::toupper;
transform(in.begin(), in.end(), back_inserter(out), fp2);
// error: too few arguments to function

または、より実際的にstd::stoiは、アルゴリズムで C++11 を使用して、文字列のベクトルを整数のベクトルに変換しようとしている人を考えてみstoiてください。2 つのオーバーロード ( string/ wstring) があり、それぞれが 2 つの追加の既定の引数を取ります。

これらすべてのデフォルトを明示的にバインドしたくないと仮定すると、そのような呼び出しを補助関数またはラムダでラップせずにこれを行うことは不可能だと思います。完全に一般的な方法でそれを行うためのブーストラッパーまたは TMP マジックはありますか? ラッパーは好きですcall_as<char(char)>(fp2)か、call_as<int(const std::string&)>(std::stoi)それとも書くことさえできますか?

4

2 に答える 2

5

おかしいです、私は似たようなことをしていました。私が見つけた最善の方法は、次のようにラムダを使用することでした。それ以外の場合は、typedefを使用して適切なオーバーロードを取得し、std :: bindを使用してロケールを削除するか、ロケールを使用しない必要があるためです。ただし、これははるかにきれいに機能します。

static const std::locale loc;
transform(in.begin(), in.end(), back_inserter(out), [&loc](char c) {
  return std::toupper(c, loc);
});

スタティックを使用して、毎回再割り当てする手間を省きます。

または、typedefを取得して次のようにすることもできます。

 std::bind((LocaleCompare)std::toupper, std::placeholders::_1, loc); // UGLY!
于 2011-07-10T22:32:07.960 に答える
0

その関数ポインター型の typedef を作成してから、関数をキャストする必要があります。

typedef char (*LocaleToUpper)(char, const std::locale&) ;
char (*fp2)(char, const std::locale&) = (LocaleToUpper)toupper;
于 2011-07-08T22:52:22.633 に答える