Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.68/37: Рейтинг темы: голосов - 37, средняя оценка - 4.68
13 / 13 / 1
Регистрация: 19.10.2019
Сообщений: 607

std::is_invokable не работает для фунций членов

19.12.2019, 16:08. Показов 8032. Ответов 108
Метки нет (Все метки)

Это так и должно бытьили я чтото неправильно делаю ?
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
19.12.2019, 16:08
Ответы с готовыми решениями:

Не работает std::cout || std::cin
#include "Account.h" #include <string> #include <iostream> using std::cout; Account :: Account(int startBalance) { ...

Операция std::cout для Объекта типа std::string
Кто детально объяснит почему не выводит ? Дает вот так "Отсутствует оператор "<<", соответствующий этим операндам" ...

Не воспринимает ни std::cout, ни std::cin. Вобщем ничего из std. Также не понимает iostream
Здравствуйте! Я хотел начать изучать язык C++. Набрал литературы. Установил Microsoft Visual C++ 2005 Express Edition. Образ диска...

108
63 / 46 / 11
Регистрация: 27.12.2017
Сообщений: 1,484
20.12.2019, 19:57
DrOffset, а что такое функции-члены? В чем отличие между обычными функциями и функциями-членами?
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13207 / 6841 / 1823
Регистрация: 18.10.2014
Сообщений: 17,304
20.12.2019, 19:58
Цитата Сообщение от squareroot Посмотреть сообщение
Ну допустим, хотя я хотел бы поподробнее про общий знаментель. Как функцию член и обучную функцию привести к общему знаменателю ?
Завернуть вызов этой функции в шаблонный функциональный объект с "общим" интерфейсом (т.е. неявный параметр this становится первым явным) и уже фактически вызов делать где-то внутри этого функционального объекта. То есть "общим знаменателем" будет именно функциональный объект с перегруженным оператором () и каким-то внутренним состоянием. (Еще раз, превратить, например, void (Class::*)(int) в void (*)(Class *, int) невозможно, то есть использовать обычные указатели на функции в качестве "общего знаменателя" не получится).

Прямую реализацию такого шаблонного функционального объекта придется специализировать отдельно для обычных функций и для методов классов. Т.е. внешне на этапе компиляции вызовы таких функциональных объектов будут выглядеть единообразно (т.е. параметр this уже вытащен на белый свет и поставлен в один ряд с остальными параметрами). Но типы таких функциональных объектов будут разными и несовместимыми для разных специализаций, т.е. например для void (Class::*)(int) и для void (*)(Class *, int), несмотря на то, что вызовы будут выглядеть одинаково.

Однако далее поверх этого можно применить технику type erasure (заплатив за это производительностью) и свести все эти несовместимые типы к одному типу для вызовов с одним и тем же набором параметров. И вы получите ни что иное как std::function, который полностью скрывает внутри себя разницу между void (Class::*)(int) и void (*)(Class *, int).
0
19501 / 10106 / 2461
Регистрация: 30.01.2014
Сообщений: 17,825
20.12.2019, 20:12
Цитата Сообщение от ReYalp Посмотреть сообщение
а что такое функции-члены?
Функции класса.
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
20.12.2019, 22:30
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Еще раз, превратить, например, void (Class::*)(int) в void (*)(Class *, int) невозможно
https://rextester.com/DJSUPO92322
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13207 / 6841 / 1823
Регистрация: 18.10.2014
Сообщений: 17,304
20.12.2019, 22:39
Цитата Сообщение от hoggy Посмотреть сообщение
Это, в смысле, юмор?
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
20.12.2019, 22:46
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Это, в смысле, юмор?
это в смысле, превратить, например, void (Class::*)(int) в void (*)(Class *, int) вполне себе возможно.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13207 / 6841 / 1823
Регистрация: 18.10.2014
Сообщений: 17,304
20.12.2019, 23:13
Цитата Сообщение от hoggy Посмотреть сообщение
это в смысле, превратить, например, void (Class::*)(int) в void (*)(Class *, int) вполне себе возможно.
Нет, разумеется. Невозможно. В вашем примере ничего подобного нет.

(Непонятно даже, зачем вы занимались всеми этими ненужными манипуляциями с указателями в своем примере, если ту же самую "картонную дурылку" можно было получить единственным вызовом memcpy.)
0
13 / 13 / 1
Регистрация: 19.10.2019
Сообщений: 607
20.12.2019, 23:16  [ТС]
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Нет, разумеется. Невозможно. В вашем примере ничего подобного нет.

(Непонятно даже, зачем вы занимались всеми этими ненужными манипуляциями с указателями в своем примере, если ту же самую "картонную дурылку" можно было получить единственным вызовом memcpy.)
memcpy это функция языка Си.... Но преобразование и вправду сомнительное и главное небезопасное.
За такое по рукам многие тимлиды надают.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13207 / 6841 / 1823
Регистрация: 18.10.2014
Сообщений: 17,304
20.12.2019, 23:23
Цитата Сообщение от squareroot Посмотреть сообщение
memcpy это функция языка Си....
Чего? В С++ уже нет memcpy? Ах, сорри, я забыл: std::memcpy.

Цитата Сообщение от squareroot Посмотреть сообщение
Но преобразование и вправду сомнительное и главное небезопасное.
Никакого "преобразования" в этом примере нет. Если переинтерпретация паимяти, напрямую запрещенная правилами языка.

Разумеется, любой человек с мало мальским практическим опытом в С++ сразу заметит, что размер указателя на метод в корректной реализации обычно отличается от размера обычного указателя на функцию, по каковой причине никакой переинтерпретацией или преобразованием, как ни верти, первый во второй запихнуть не получится.
0
13 / 13 / 1
Регистрация: 19.10.2019
Сообщений: 607
20.12.2019, 23:31  [ТС]
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Чего? В С++ уже нет memcpy? Ах, сорри, я забыл: std::memcpy.
эти функции пришли из Си. А то что их засуули в неймспейс std это у них такая судьба злая :-)

Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Никакого "преобразования" в этом примере нет. Если переинтерпретация паимяти, напрямую запрещенная правилами языка.

Разумеется, любой человек с мало мальским практическим опытом в С++ сразу заметит, что размер указателя на метод в корректной реализации обычно отличается от размера обычного указателя на функцию, по каковой причине никакой переинтерпретацией или преобразованием, как ни верти, первый во второй запихнуть не получится.
Free f = *((Free*)proxy);
Вы очевидно не заметли явного приведения к типу Free*. С явным приведением возможно, но такое преобразование относится к небезопасным.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13207 / 6841 / 1823
Регистрация: 18.10.2014
Сообщений: 17,304
20.12.2019, 23:48
Цитата Сообщение от squareroot Посмотреть сообщение
эти функции пришли из Си. А то что их засуули в неймспейс std это у них такая судьба злая :-)
Это совершенно не важно, откуда они пришли. Тот момент, который вам нужно понять, это то, что функция memcpy является в совершенно одинаковой мере С++ и С функцией. Никакого "это функция С" тут нет и быть не может.

Цитата Сообщение от squareroot Посмотреть сообщение
Вы очевидно не заметли явного приведения к типу Free*.
Вы, очевидно, не заметили, что целью "приведения" в данном случае является получение значения типа Free. Именно Free, а не Free *. Тип Free уже содержит внутри себя указатель.

А приведение к Free * - это не более чем "пионэрский" способ (в общем случае - неработоспособный), которым аффтар выполнил переинтерпретацию памяти. Это деталь, которая к делу не относится вообще никак. Как я сказал выше, можно было обойтись просто memcpy.

Цитата Сообщение от squareroot Посмотреть сообщение
С явным приведением возможно, но такое преобразование относится к небезопасным.
"Небезопасным" здесь является то, как используется результат этого преобразования - язык С++ напрямую запрещает такое использование, как вызывающее неопределенное поведение уже само по себе. Вариант с memcpy был бы свободен от именно этой проблемы, но все равно был бы бесполезной "пионэрской" тратой времени. Я уже закрыл этот вопрос раз и навсегда выше. Процитирую самого себя еще раз:

"Разумеется, любой человек с мало мальским практическим опытом в С++ сразу заметит, что размер указателя на метод в корректной реализации обычно отличается от размера обычного указателя на функцию, по каковой причине никакой переинтерпретацией или преобразованием, как ни верти, первый во второй запихнуть не получится."
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
21.12.2019, 00:04
Цитата Сообщение от squareroot Посмотреть сообщение
преобразование и вправду сомнительное и главное небезопасное
суть не в том, безопасное оно или нет.
суть в том, что преобразование возможно.

Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Никакого "преобразования" в этом примере нет. Если переинтерпретация паимяти
если ты вдруг не в курсе: "переинтерпретация" и есть "преобразование".
в контексте преобразования типов указателей это - синонимы.

Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Непонятно даже, зачем вы занимались всеми этими ненужными манипуляциями с указателями в своем примере, если ту же самую "картонную дурылку" можно было получить единственным вызовом memcpy.
для того, что бы преобразовать один тип указателя в другой,
memcpy не нужен.

приведенный мною фрагмент - пример-иллюстрация того,
чем на самом деле является указатель-на-функцию-член.

иногда новички спрашивают:
"чем указатель-на-функцию-член отличается от обычных функций?"

я объясняю им: технически, функция-член-класса - это самая обычная функция.
в которую компилятор неявно для программиста запихивает указатель this.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13207 / 6841 / 1823
Регистрация: 18.10.2014
Сообщений: 17,304
21.12.2019, 00:18
Цитата Сообщение от hoggy Посмотреть сообщение
суть не в том, безопасное оно или нет.
суть в том, что преобразование возможно.
Нет, не возможно. Я этот вопрос закрыл выше и повторять одно и то же в третий раз не буду. Читайте и зубрите до прояснения.


Цитата Сообщение от hoggy Посмотреть сообщение
если ты вдруг не в курсе: "переинтерпретация" и есть "преобразование".
в контексте преобразования типов указателей это - синонимы.
Бред полный. В С и С++ переинтерпретация памяти никогда и ни в коем случае не является синонимом преобразования.

Что характерно, в стандартной терминологии типы указатель-на-член по определению НЕ являются указательными типами именно потому (!), что внутренняя структура и размер указателя-на-член не имеет ничего общего с обычными указателями. Поэтому ни о каких "синонимах", "переинтерпретациях" и "преобразованиях" речи быть не может.

Цитата Сообщение от hoggy Посмотреть сообщение
приведенный мною фрагмент - пример-иллюстрация того,
чем на самом деле является указатель-на-функцию-член.
иногда новички спрашивают:
"чем указатель-на-функцию-член отличается от обычных функций?"
я объясняю им: технически, функция-член-класса - это самая обычная функция.
в которую компилятор неявно для программиста запихивает указатель this.
Приведенный вам пример - иллюстрация полного грубейшего отсутствия опыта. Из-за которого вы глюк конкретного компилятора приняли за какое-то откровение об устройстве указателя-на-член. Да еще и, оказывается, распространяете подобные бредни среди начинающих.

Причем, что характерно, компилятор MSVC++ прекрасно знает, что его реализация указателей-на-член неработоспособна, и предоставляет возможность включить работоспособную реализацию. Но вы, разумеется, не можете себе позволить пользоваться корректной реализацией, ибо тогда ваша "картонная дурылка" накроется медным тазом во все воронье горло
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
21.12.2019, 00:39
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Нет, не возможно.
есть два типа людей.
первые приводят рабочий код, который иллюстрирует возможность.
вторые, несмотря на наличие рабочего примера, продолжают тупить,
отказываясь признать: таки да, возможно.

Цитата Сообщение от TheCalligrapher Посмотреть сообщение
В стандартной терминологии типы указатель-на-член по определению НЕ являются указательными типами
не принципиальный фактор.
принципиально, что обращение к объекту некоторого типа,
как к объекту другого типа - есть реинтерпритация.

Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Из-за которого вы глюк конкретного компилятора
это не глюк конкретного компилятора.
это - "глюк" как минимум всех топовых компиляторов: gcc/cl/clang

и не надо заливать про опыт.
в коде даже комментарий есть о незаконном преобразовании.

такое впечатление, что ты не так и не врубился зачем был нужен этот пример.

пример наглядно иллюстрирует:
Цитата Сообщение от hoggy Посмотреть сообщение
технически, функция-член-класса - это самая обычная функция.
в которую компилятор неявно для программиста запихивает указатель this.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13207 / 6841 / 1823
Регистрация: 18.10.2014
Сообщений: 17,304
21.12.2019, 00:45
Цитата Сообщение от hoggy Посмотреть сообщение
есть два типа людей... первые приводят рабочий код, который иллюстрирует возможность.
(Снова вспомнился меткий анекдот про "таракан без но не слышит")

Я думаю, что здесь все уже ясно. Проку не будет.

Я всегда говорил, что понимание концепций языков программирования - это вопрос "взрослости" студента. Пытаться объяснять их раньше времени - это примерно то же самое, что пытаться объяснять пятилетнему ребенку тонкости семейных отношений. Пока студент не "дорастет" до определенной стадии в своем развитии, сколько времени ни трать на вбивание в эту бошку знаний, пользы никакой не будет.

Остается только надеяться, что все рано или поздно "дорастают" до этой стадии. Хотя и это, боюсь, не гарантировано.
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
21.12.2019, 00:54
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Я всегда говорил, что понимание концепций языков программирования - это вопрос "взрослости" студента.
есть разница между: "невозможно" и "возможно, хоть и не вполне законно".
по видимому, не всем студентам дано это понять.
0
13 / 13 / 1
Регистрация: 19.10.2019
Сообщений: 607
21.12.2019, 00:57  [ТС]
Цитата Сообщение от hoggy Посмотреть сообщение
есть разница между: "невозможно" и "возможно, хоть и не вполне законно".
по видимому, не всем студентам дано это понять.
Почему не вполне законно ?
ISO 14882-2011 4.3
An lvalue of function type T can be converted to a prvalue of type “pointer to T.” The result is a pointer to
the function.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13207 / 6841 / 1823
Регистрация: 18.10.2014
Сообщений: 17,304
21.12.2019, 01:02
Цитата Сообщение от hoggy Посмотреть сообщение
есть разница между: "невозможно" и "возможно, хоть и не вполне законно".
Нет, зайчик вы наш, даже "не вполне законно" невозможно. Я уже десять раз повторил, что полноценный указатель-на-член в любой корректной реализации превосходит обычный указатель по размеру в разы, ибо содержит еще массу абсолютно необходимой служебной информации. По каковой причине всем здесь совершенно очевидно, что запихать его в обычный указатель не получится никак, ни приведениями, ни переинтерпретациями, ни memcpy. Никак.

Именно по этой причине ваша "картонная дурылка", который вы сами же и обманулись, может рассматриваться лишь как пример плохого юмора.
0
13 / 13 / 1
Регистрация: 19.10.2019
Сообщений: 607
21.12.2019, 01:09  [ТС]
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Нет, зайчик вы наш, даже "не вполне законно" невозможно. Я уже десять раз повторил, что полноценный указатель-на-член в любой корректной реализации превосходит обычный указатель по размеру в разы, ибо содержит еще массу абсолютно необходимой служебной информации. По каковой причине всем здесь совершенно очевидно, что запихать его в обычный указатель не получится никак, ни приведениями, ни переинтерпретациями, ни memcpy. Никак.

Именно по этой причине ваша "картонная дурылка", который вы сами же и обманулись, может рассматриваться лишь как пример плохого юмора.
А какое отношение ваше утверждением имеет к правилас языка C++ ?
Какие виды адрессациии применяет компилятор при компиляции кода никакого отношения к языку C++ не имеют, хотя безусловно разработчики компиляторов делают своё решение максимально оптимально, а потому чтото во чтото запихнуться не может, но это никакого отношения к данному вопросу не имеет.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13207 / 6841 / 1823
Регистрация: 18.10.2014
Сообщений: 17,304
21.12.2019, 01:11
Цитата Сообщение от squareroot Посмотреть сообщение
Почему не вполне законно ?
ISO 14882-2011 4.3
An lvalue of function type T can be converted to a prvalue of type “pointer to T.” The result is a pointer to
the function.
???

Процитированный вами отрывок говорит, что, например, lvalue типа void () можно [неявно] преобразовать к типу void (*)(). То есть к рассматриваемому вопросу он вообще никак не относится.

К функциям-нестатическим членам класса это тоже не относится никак. Функции-члены класса не являются "lvalue of function type". "Lvalue of function type" в С++ по определению бывает только для самостоятельных функций.

Добавлено через 1 минуту
Цитата Сообщение от squareroot Посмотреть сообщение
А какое отношение ваше утверждением имеет к правилас языка C++ ?
Прямое. Каждое сказанное мною до сих пор слово - прямая цитата правил языка С++.

Цитата Сообщение от squareroot Посмотреть сообщение
Какие виды адрессациии применяет компилятор при компиляции кода никакого отношения к языку C++ не имеют, хотя безусловно разработчики компиляторов делают своё решение максимально оптимально, а потому чтото во чтото запихнуться не может, но это никакого отношения к данному вопросу не имеет.
Набор слов. Не пропарсил.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
21.12.2019, 01:11

std::string код работает в VS 6.0, но не работает в VS2012 (error C4996)
Как изменился синтаксис в Visual Studio 2012 данной строки? В VS 6.0 работает, в 2012 - нет. Кто подскажет, где можно взять список...

ошибка error: cannot convert 'std::string {aka std::basic_string<char>}' to 'std::string* {aka std::basic_stri
на вод поступают 2 строки типа string. определить количество вхождений строки 2 в строку 1 ошибка error: cannot convert 'std::string {aka...

STL std::set, std::pair, std::make_pair
Я не знаю как описать тему в двух словах, поэтому не обращайте внимание на название темы. Собственно перейдем к нашим баранам: есть...

Для заданной матрицы найти такие k и n, что сумма членов k-го столбца совпадает с суммой членов n-й строки
Нужно написать фрагмент кода: Для заданной матрицы размера NхN найти такие k и n, что сумма элементов k-столбца матрицы совпадает с...

На основе исходного std::vector<std::string> содержащего числа, создать std::vector<int> с этими же числами
подскажите есть вот такая задача. Есть список . Создать второй список, в котором будут все эти же числа, но не в виде строк, а в виде...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
Контроль уникальности строк в табличной части документа
Maks 18.06.2026
Алгоритм из решения ниже разработан на примере нетипового документа "ПланированиеСпецтехники" с табличной частью "НаличиеОборудования", разработанного в КА2. Задача: контроль уникальности строк в. . .
Клиент
Uhbif79 18.06.2026
Здесь простой клиент для работы с сервером.
Сервер
Uhbif79 18.06.2026
Выкладываю простейший сервер.
Дефенестрация
kumehtar 18.06.2026
Узнал интересное слово. Дефенестрация. Это когда ты выбрасываешь кого-либо или что-либо из окна. Возьму на вооружение)))
Дихотомия добра и зла
kumehtar 18.06.2026
Как Дзен-буддисты говорят о добре и зле: не нужно воевать против зла, нужно воевать против невежества. Тогда добро станет ествественным, и поэтому вечным. Но дело в том, что невежество всё время. . .
Своя Интернет-Компания
iceja 18.06.2026
Я программист с экономическим образованием, пишу свой проект, это SaaS для бизнесов. Мне нужен co-founder с высшим экономическим образованием, и/ или инвестор. Сейчас проект в интенсивной разработке,. . .
24 Мат модель здравосохранения: функциональные требования к строительству пищеблока
anaschu 18.06.2026
СРесурсами1: финансовый SD-контур, калькулятор функциональных требований пищеблока Сегодня разделили затраты в агенте Экономика по образцу модели НАСОСЫ, добавили расчёт ROI и построили первый. . .
23. что сделано за последнее время.
anaschu 17.06.2026
• Эталон: Клиника НИИ питания РАМН, Москва — централизованный пищеблок, 225 коек, 180 пациентов • Git: репозиторий med2, ветка абсентеизм. Рабочий файл: СРесурсами1_v4. alp • Смежный проект:. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru