Суть в том, что то, что вы пытаетесь сделать, невозможно в portable C ++. std::vector<>::push_back
гарантированно будет перегружено в компиляторах C ++ 11, поскольку как минимум должна быть перегрузка для lvalues и перегрузка для rvalues.
Обычно , принимая адрес перегруженной функции-члена, §13.4 / 1 в FDIS C ++ 11 говорит нам, что мы можем контролировать, какую перегрузку мы получаем адрес, таким образом:
Использование имени перегруженной функции без аргументов разрешается в определенных контекстах функции, указателем на функцию или указателем на функцию-член для конкретной функции из набора перегрузок. Имя шаблона функции считается именем набора перегруженных функций в таких контекстах. Выбранная функция - это та, чей тип идентичен типу функции целевого типа, необходимого в контексте. [ Примечание: То есть класс, членом которого является функция игнорируется при сопоставлении типа указатель на функцию-член. - Конечная заметка ] Цель может быть
- инициализируемый объект или ссылка,
- левая сторона задания,
- параметр функции,
- параметр пользовательского оператора,
- возвращаемое значение функции, операторской функции или преобразования,
- явное преобразование типа или
- нетипизированный шаблон-параметр.
Перед именем перегруженной функции может стоять оператор &
. Перегруженное имя функции не должно использоваться без аргументов в контекстах, отличных от перечисленных. [ Примечание: Любой избыточный набор скобок, окружающих имя перегруженной функции, игнорируется. - Конечная заметка ]
Проблема исходит из §17.6.5.5 / 2:
Реализация может объявлять дополнительные не виртуальные сигнатуры функций-членов в классе, добавляя аргументы со значениями по умолчанию к сигнатуре функции-члена; следовательно, адрес функции-члена класса в стандартной библиотеке C ++ имеет неопределенный тип.
Следовательно, невозможно переносить адрес стандартной функции-члена класса библиотеки, так как тип такого выражения по определению неизвестен, за исключением случаев реализации на основе.
Предложенный Люком Дантоном обходной путь (в частности, с использованием лямбды) также является тем, что я бы порекомендовал:
std::vector<int> vec;
[&](){ vec.push_back(1); }();