- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
#include <iostream>
#include <algorithm>
#include <functional>
#include <map>
#include <string>
int main()
{
using namespace std::placeholders;
std::map<std::string, int> karta;
std::vector<std::string> goroda{ "foo", "bar", "foo" };
std::for_each(goroda.begin(), goroda.end(), std::bind(
static_cast<
std::pair<decltype(karta)::iterator, bool>
(decltype(karta)::*)(const decltype(karta)::key_type&, decltype(karta)::mapped_type&&)>
(&decltype(karta)::insert_or_assign),
std::ref(karta),
_1,
std::bind(
std::plus<decltype(karta)::mapped_type>(),
1,
std::bind(
static_cast<decltype(karta)::mapped_type&(decltype(karta)::*)(const decltype(karta)::key_type &)>
(&decltype(karta)::operator[]),
std::ref(karta),
_1))
));
std::cout << "foo: " << karta["foo"] << "\nbar: " << karta["bar"] << '\n';
return EXIT_SUCCESS;
}
Проблема в том, что operator[] и insert_or_assign() — перегружены, поэтому нам надо явно задать возвращаемые и принимаемые типы. В коде это делается через приведение к указателю на функцию нужного вида.
Хотя, с другой стороны, логичная - при вызове же функция выбирается автоматически по аргументам, ну и тут происходит похожее.
Перегрузки в объектном файле имеют разные имена (google: mangling). Допустим, нужно написать функцию sin для разных типов данных:
В объектном файле (и в ассемблере, если компиляция идёт через ассемблер) они будут именоваться как-то так:
Нечитаемые символы я написал наобум. Главное здесь, что где-то в добавленны символах зашифрованы имена типов аргументов (я добавил f, d, ld).
Так вот компилятору нужно знать, какую из этих функций подставить. При компиляции вызова он пытается угадать, какого типа аргументы (если аргументы являются переменными, то это легко; если же выражения, то нужно подобрать ближайший тип, чтобы и результат не испортился, и перегрузка нашлась).
Взятие же адреса перегруженной функции тяжело реализовать, потому что компилятор должен подобрать какой-нибудь из вариантов... Как ему указать вариант, если аргументов нет?
Правда, там тоже любят чуток мангальнуть (winmain@16). Тут 16 это понятно что, да?
но это ибет только линкера (или лоадера) коий шукает ее чтобы сделать точкою входа
а вот обычные функции конечно экспортятся нормально, так что там можно взять указатель на функцию вообще влегкую. Именно потому я за си
Да, и __cdecl, и __syscall, и __pascal, и собственный __watcall там где-то заданы прагмой и их можно переопределять. Шаблон "_ *@nnn" здесь означает добавить впереди знак подчёркивания и в конце собаку и размер аргументов.
это чтобы писать не на сишечке а на япах коие ее умеют?
а поцкаль умел?
невиртуальная тоже?
В «PHP» нет перегрузки функций, поэтому сделать точный перевод нельзя.
Или даже:
https://ideone.com/fi12E8
Подробнее: https://en.cppreference.com/w/cpp/utility/functional/bind