Как использовать перегруженные функции с аргументами по умолчанию в алгоритмах? - PullRequest
10 голосов
/ 07 июля 2011

Я знаю ответ на часто задаваемый вопрос Как указать указатель на перегруженную функцию? : либо с присваиванием, либо с приведением, и с любыми другими прописными буквами учебника 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

Или, на практике, кто-то пытается использовать C ++ 11 std::stoi в алгоритме для преобразования вектора строк в вектор целых чисел: stoi имеет две перегрузки (string / wstring ), каждый из которых принимает два дополнительных аргумента по умолчанию.

Предполагая, что я не хочу явно связывать все эти значения по умолчанию, я считаю, что это невозможно сделать без включения такого вызова во вспомогательную функцию или лямбду. Есть ли у меня бустер-обертка или магия TMP, чтобы сделать это для меня в общем виде? Можно ли написать обертку типа call_as<char(char)>(fp2) или, что более вероятно, call_as<int(const std::string&)>(std::stoi)?

Ответы [ 2 ]

5 голосов
/ 11 июля 2011

Забавно, я делал что-то подобное.Лучший способ сделать это - использовать лямбда-выражения следующим образом, потому что в противном случае вы должны использовать 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!
0 голосов
/ 09 июля 2011

Вы могли бы создать typedef этого типа указателя на функцию и затем привести функцию.

typedef char (*LocaleToUpper)(char, const std::locale&) ;
char (*fp2)(char, const std::locale&) = (LocaleToUpper)toupper;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...