Почему function wrapper с ссылкой в сигнатуре может принимать pointer to member function?
К примеру стандартный function wrapper - std::function.
При сигнатуре void(T&, ars...) может принимать &T::Method. Разве у всех методов не указатель первый аргумент?
При сигнатуре void(T&, ars...) может принимать &T::Method.
Такая сигнатура определяет тип функции, а не метода. При чем тут метод?
Разве у всех методов не указатель первый аргумент?
Нет. В принципе - нет.
Метод - это метод. Функция - это функция. Чисто ради прикола возьми и сравни размер указателя на метод и указателя на функцию.
Плюсом есть соглашения о вызовах и вангуя о неявном аргументе this, я говорю что не всегда оно так, как у тебя в цитате. this может приходить вообще не так, как приходят аргументы.
Dyikot, методы и не принимают. Метод по его указателю можно выполнить только относительно объекта своего типа. Передать в него this иным образом невозможно.
Я тебя все еще не понимаю.
template<typename TSender, typename TEventArgs.
using EventHandler = std::function<void(TSender&, TEventArgs)>;
Всегда думал что методы просто функции которые первым аргументом принимают указатель на объект класса, и тут получается он может принимать и ссылку на объект класса. И вот вопрос был как можно оба? Или ссылка неявно к указаетлю преобразовывается. Все равно в памяти один вариант должен быть.
И ты показываешь делегат. А про function wrapper я и всё остальное общество ничего не знаем. Это что-то твоё личное и поэтому другой человек тебя не понимает. Потому что ты говоришь на каком-то другом языке. Не на языке общих терминов.
Всегда думал что методы просто функции которые первым аргументом принимают указатель
Однако так никогда не было. Ты заблуждаешься уже начиная с этого убеждения. А ведь понятие метода - фундаментальное. Т.е. у тебя фундаментальные заблуждения.
Или ссылка неявно к указателю преобразовывается.
Ссылка - это синтаксический эфемер. Указатель - это тип данных. И как тут одно к другому привести?
Ты очень сильно путаешься.
Делегат, т.е. std::function, не умеет захватывать указатели на методы. Он умеет захватывать только указатели на функции или функциональные объекты по значению. Когда тебе нужно через делегат вызвать метод объекта, тебе нужно знать целевой объект для метода, захватить этот объект в замыкании лямбды, в теле которой и вызвать относительно объекта метод. И уже эту лямбду сможет захватить делегат.
По значению.
Когда ты пишешь
template<typename TSender, typename TEventArgs.
using EventHandler = std::function<void(TSender&, TEventArgs)>;
то EventHandler<MyType> не начнет для тебя принимать методы. Он будет принимать просто указатели функции, первым аргументом которых ожидается ссылка на объект типа MyType.
Евгений Шатунов, 1) В качетсве примера function wrapper я и использую std::function, а не свою реализацию чтобы все поняли. Определение std::function взято из cppreference
Class template std::function is a general-purpose polymorphic function wrapper.
2)
Делегат, т.е. std::function, не умеет захватывать указатели на методы.
И ты в серьез уверен в том, что если что-то скомпилировалось на выбранном тобой трансляторе и с выбранными тобой настройками компиляции, то оно будет с тем же успехом компилироваться всеми трансляторами и со всеми настройками?
Ты ведь пользуешься тем, что не понимаешь не просто хоть как-то, а прямо совсем не понимаешь.
Есть только один способ убедиться в правильности написанного кода - это найти в стандарте точное место, где объясняется поведение написанного тобой кода. Если такого объяснения нет, если объяснение отличается между версиями стандарта или отсутствует в других версиях стандарта, то такой код не надежен.
Вот документ примерно 11-го стандарта. Буквально следующая же ревизия документа распространяется за деньги как финальная версия 11-го стандарта.
Предлагаю тебе найти описание поведения приведенного тобой кода.
В качетсве примера function wrapper я и использую std::function, а не свою реализацию чтобы все поняли. Определение std::function взято из cppreference
Я все это понимаю, но прямо говорю тебе не делать таких вводящих в заблуждение вещей. Если тебе хочется оперировать емкими терминами, используй только термины из набора шаблонов проектирования. Тогда тебя поймут правильно уже с большей вероятностью.
Евгений Шатунов, Почему это не должно работать на других компиляторах? И причем тут настройки компилятора? Это может не работать если в реализации делегата не будет соответсвенной проверки типа и соотвенно правильного вызова указателя на метод. Если на cppreference про стандарный делегат есть соответсующее описание что это поддерживается то тогда я считаю что это стандарт.
Instances of std::function can store, copy, and invoke any CopyConstructible Callable target -- functions (via pointers thereto), lambda expressions, bind expressions, or other function objects, as well as pointers to member functions and pointers to data members.