LINUX.ORG.RU

c++ Вопросик с лямбда

 ,


0

2

Продолжаю изучать с++ ) Загвоздка с лямбда


class Process {
public:

  int (*onReady)(const char*);  
  std::string outpurBuffer;
}

Process *proc = new Process();
proc->onReady = [](const char* reason) {
  std::string = proc->outpurBuffer;
  return 1;
};


Не работает, говорит что локальную переменную нельзя. Гуглю соответственно «c++ local variable in lambda», первый пример указывает что нужно в скобки квадратные передавать Captured variables

// Local Variables
std::string msg = "Hello";
int counter = 10;
// Defining Lambda function and
// Capturing Local variables by Value
auto func = [msg, counter] () {
                          //...
                          };

ок, делаю
proc->onReady = [proc](const char* reason) {
  std::string s = proc->outpurBuffer;
  return 1;
};

Снова ошибка, но уже с приведением типов. Что не так?

Кстати сразу другой вопросик, чем отличается
const char* reason;
const char *reason;

Есть ли разница? Компилятору я смотрю без разницы, то и то проглатывает

★★★★

Последнее исправление: gobot (всего исправлений: 1)
Ответ на: комментарий от anonymous

Да нет же. Когда две переменные так через запятую объявлены, то вторая имеет просто тип char.

rumgot ★★★★★
()
Ответ на: комментарий от rumgot

Буду использовать. А больше ничего не остается

gobot ★★★★
() автор топика
Ответ на: комментарий от rumgot

Странно, почему тогда я ее без std:: вызываю? Using не использую. Может дебагер сам подключает std? Вообще я думал что это функция с, типа malloc

gobot ★★★★
() автор топика
Ответ на: комментарий от gobot

Странно, почему тогда я ее без std:: вызываю?

Потому что стандарт разрешает «сишным» функциям быть доступными также в глобальном неймспейсе.

anonymous
()
Ответ на: комментарий от PRN

Я там выше привел текст из стандарта. Что там явно написано, что есть функция преобразования в указатель на функцию.

Кстати вот:

#include <iostream>

int main() {
    auto l = []() { std::cout << "Lambda called" << std::endl; };
    l();
    // по моему это явно не вызов статической функции
    l.operator()();
    void (*pl)() = l;
    pl();
}

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

rumgot ★★★★★
()
Ответ на: комментарий от hobbit

Во-первых, красивое иностранное слово, которым ты решил щегольнуть, ты употребил не по делу. «Ньюфаг» — это не синоним «новичка» или «нуба», это слово, которым означают поклонника всего нового (как правило, неразборчивого).

Ты из какой-то альтернативной реальности.

https://en.wiktionary.org/wiki/newfag:

(Internet slang, derogatory) A n00b

https://en.wiktionary.org/wiki/n00b:

(Internet slang, leetspeak, derogatory, leet slang) A beginner, someone lacking skill

Во-вторых, лямбды — это фича C++11, которую продолжали развивать во всех последующих стандартах. Прибавь, что до компиляторов эти новшества обычно едут несколько лет

Фичи сначала добавляют в компиляторы (пусть и в экспериментальные ветки), потом только в стандарт. Фичи, для которых не удаётся реализовать хоть где-то к выходу стандарта, из стандарта выпиливаются и откладываются до следующей редакции. (Разумеется, в прошлом были исключения типа экспорта шаблонов, но это была ошибка на которой научились.)

В третьих, лямбды — объективно сложный материал … Поэтому — отстань от новичка.

У тебя логическая ошибка в рассуждениях. То, что в лямбдах есть сложный материал не делает любой вопрос про лямбды сложным. Вопрос ОП-а — ньюфажный.

anonymous
()
Ответ на: комментарий от gobot

тебе надо определиться что ты хочешь сделать. если ты хочешь вызывать strlen(), то в конце строки должен быть ноль. если ноля в конце строки по какой-то причине нет, то надо вызывать strnlen(). либо не вызывай вообще никакой вариант, функция чтения и так тебе вернёт сколько байт было прочитано - используй это значение.

если же ты хочешь сначала вытирать нули, а затем вызывать функцию которая ищет ноль, то ничего хорошего тебя не ждёт, от языка это не зависит.

можешь ещё валгринд запустить, он тебе эту ошибку сразу бы показал.

anonymous
()
Ответ на: комментарий от anonymous

Фичи сначала добавляют в компиляторы (пусть и в экспериментальные ветки), потом только в стандарт

Хрен там плавал. Вот тут https://en.cppreference.com/w/cpp/compiler_support посмотри сколько пунктов не реализовано в компиляторах из стандарта C++20.

rumgot ★★★★★
()
Последнее исправление: rumgot (всего исправлений: 1)
Ответ на: комментарий от rumgot

// по моему это явно не вызов статической функции l.operator()();

Как будто статические функции нельзя так вызывать… (Но так да, operator() у лямбды это никогда не статическая функция).

anonymous
()
Ответ на: комментарий от anonymous

Как будто статические функции нельзя так вызывать

Ну ты же понимаешь, что operator() - в принципе не может быть объявлен как статическая функция.

rumgot ★★★★★
()
Ответ на: комментарий от fsb4000

Просто когда нет захвата, он реализует метод как статический метод класса

operator() вообще не может быть статическим членом.

anonymous
()
Ответ на: комментарий от rumgot

Вот тут https://en.cppreference.com/w/cpp/compiler_support посмотри сколько пунктов не реализовано в компиляторах из стандарта C++20.

Целых два. Для всего, кроме «constexpr std::string» и «constexpr std::vector» есть хотя бы одна реализация.

anonymous
()
Ответ на: комментарий от fsb4000

О круто, спасибо. А ведь почти так оно и получается, как я предполагал.

rumgot ★★★★★
()
Ответ на: комментарий от rumgot

Давай так: лямбды до компиляторов ещё не доехали? Если доехали, то смысл реплики

Во-вторых, лямбды — это фича C++11, которую продолжали развивать во всех последующих стандартах. Прибавь, что до компиляторов эти новшества обычно едут несколько лет

в чём?

anonymous
()
Ответ на: комментарий от anonymous

Стояночка. Это не моя реплика. Я оспорил утверждение:

Фичи сначала добавляют в компиляторы (пусть и в экспериментальные ветки), потом только в стандарт

rumgot ★★★★★
()
Ответ на: комментарий от rumgot

Глянул стенограмму обсуждений пропозала про строки. Пишут, что есть сторонняя реализация. Реализация в стандартных библиотеках зависела от добавления одной фичи в компиляторы. Решили, что реализуемость пропозала достаточно очевидна и смёржили в стандарт до реализации в библиотеке хоть от какого-то вендора.

anonymous
()
Ответ на: комментарий от rumgot

Я там выше привел текст из стандарта. Что там явно написано, что есть функция преобразования в указатель на функцию.

Ну да, все верно. Стандарт описывает поведение, а не реализацию. Я для примера приводил возможную реализацию соответствующую стандарту.

l.operator()();

То что у лямбды есть operator() в стандарте тоже нет. Ты и сам кишки реализации нашел)). Но копаться в них не надо, можно себе в ногу выстрелить.

PRN
()
Ответ на: комментарий от PRN

То что у лямбды есть operator() в стандарте тоже нет.

[expr.prim.lambda.closure]

3 The closure type for a lambda-expression has a public inline function call operator…

anonymous
()
Ответ на: комментарий от anonymous

Уболтал, есть) Если точно, то даже еще и шаблонный есть

The closure type for a lambda-expression has a public inline function call operator (for a non-generic lambda) or function call operator template (for a generic lambda)

PRN
()
Последнее исправление: PRN (всего исправлений: 1)
Ответ на: комментарий от PRN

Но копаться в них не надо, можно себе в ногу выстрелить.

Нашел кому такие советы давать. Я же новичок первогодка (сарказм). Нужно и даже полезно, чтобы знать и в облаках не витать.

rumgot ★★★★★
()
Последнее исправление: rumgot (всего исправлений: 2)
Ответ на: комментарий от PRN

К тому что шаблон используется при реализации generic lambda и не используется при реализации non generic lambda.

rumgot ★★★★★
()
Ответ на: комментарий от PRN

Я привел то, как оно реализовано, а ты мне про кишки. Как именно ты их предполагаешь юзать? Вызов operator() через полное имя или приведение у указателю - это не кишки, а закрепленное стандартом поведение.

rumgot ★★★★★
()
Последнее исправление: rumgot (всего исправлений: 2)
Ответ на: комментарий от rumgot

Ты, похоже, совсем не понимаешь что тебе говорят. А тебе как раз говорят, что надо юзать официальные интерфейсы описанные стандартом. Абстракции иногда протекают. https://www.youtube.com/watch?v=S9_mYmvO4Ow

Как именно ты их предполагаешь юзать?

Откуда мне знать что ты там найдешь? Хотя пофиг, юзай что хочешь, на ошибках тоже учатся)).

PRN
()
Ответ на: комментарий от PRN

Ты, похоже, совсем не понимаешь что тебе говорят. А тебе как раз говорят, что надо юзать официальные интерфейсы описанные стандартом. Абстракции иногда протекают.

Где ты увидел в моем коде использование не стандартного интерфейса?

Не используй кишки

Как именно?

Откуда мне знать что ты там найдешь? Хотя пофиг, юзай что хочешь, на ошибках тоже учатся)).

Ха, ты что выпивши?

rumgot ★★★★★
()
Ответ на: комментарий от hobbit

«Ньюфаг» — это не синоним «новичка» или «нуба», это слово, которым означают поклонника всего нового (как правило, неразборчивого).

Да ладно?

DarkEld3r ★★★★★
()
Ответ на: комментарий от gobot

Сишная классика, а не костыль. Груз совместимости. Может имеет смысл вначале чистый Си изучить?

Psilocybe ★★★★★
()
Ответ на: комментарий от AdonisSexyBoy

Да, с ньюфагом был неправ, признаю.

Но анонимус к ТСу примотался всё равно зря.

hobbit ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.