Berkus
VS может хоть рак диагностировать
Constantine
VS может хоть рак диагностировать
пруфы со стандарта или не было
Berkus
не было
Aidar
Годно
Constantine
а вообще на стандарте C++ уже парадокс лжеца на noexcept вбрасывали, так что всегда может быть тупо бага стандарта
Berkus
баги в стандарте бывают конечно
Constantine
struct A { struct B { int i = (A(), 0); }; A() noexcept(!noexcept(B())); };
Aidar
У меня не собрало
Constantine
разумеется, это парадокс лжеца
Constantine
стандарт разрешает все это использовать
Aidar
Это ошибка не компилятора а программиста
Aidar
Это заведомо неразрешимая штука
Constantine
не, это код, разрешенный по стандарту
Aidar
Но не разрешенный по логике
Constantine
стандарт разрешает использовать определение A в коде B и определение B в коде А
Aidar
Так в чем трабл
Aidar
Си++ много разрешает
Constantine
что это - парадокс лжеца
Constantine
для компилятора
Constantine
без маркировки "this program is ill-formed"
Aidar
Оно ваще не formed
Constantine
короче, компилятор обязан это скомпилировать
Aidar
Он обязан скомпилировать если стандарт расскажет ожидаемый результат
Constantine
почему он имеет право отказаться компилировать код, использующий только конструкции, не запрещенные стандартом вообще?)
Aidar
Почему он должен игнорировать семантику чтоль?
Constantine
а что, он может сказать, что a, b = b, a //CE #3872: I hate python
Berkus
почему он имеет право отказаться компилировать код, использующий только конструкции, не запрещенные стандартом вообще?)
нормальный компилятор имеет право отказаться компилировать код даже если ты просто ему не нравишься, или памяти мало
Aidar
Околобесконечная рекурсия шаблонов поди тоже не запрещена стандартом
Constantine
там это технические ограничения
Constantine
а тут это просто логическая ошибка
Aidar
Это все ограничения "я не смог посчитать"
Constantine
Ну не смогла я?)
Constantine
линкер утверждает, что вот эта строка модифицирует определение типа Around::SomeStruct Around::SomeStruct::SomeStruct() : b([]() {})
Кстати, я, похоже, понял. Класс для лямбды определяется в ближайшем scope.
Anatoly
ну тогда явно баг компилятора
Constantine
почему?
Anatoly
он не имеет права принимать в расчет сгенерированные для своих нужд артефакты и приписывать их к определению класса
Constantine
вообще цитата
Constantine
The lambda expression is a prvalue expression () whose value is (until C++17)whose result object is (since C++17) an unnamed temporary object of unique unnamed non-union non-aggregate class type, known as closure type, which is declared (for the purposes of ADL) in the smallest block scope, class scope, or namespace scope that contains the lambda expression
Максим
Че там с пропозалами? Ответили?
Anatoly
компилятор может для своих нужд (for the purposes of ADL) создавать все что угодно, это тем не менее не нарушает ODR, поскольку по факту у тебя одно определение
🐙 Antony
Я не поеду по семейным обстоятельствам. Но буду следить из дома )
🐙 Antony
Читать вики, и стенограмы заседаний
Constantine
Я немного почитал стандарт. Я не нашел гарантию, что closure type для lambda, объявленной внутри function template имеет тип, не зависящий от Translation Unit
Anatoly
при инстанцировании шаблона функции скопом для closure type лямбды будет само тело инстанцированной функции
🐙 Antony
Я немного почитал стандарт. Я не нашел гарантию, что closure type для lambda, объявленной внутри function template имеет тип, не зависящий от Translation Unit
[basic.link] When a name has no linkage, the entity it denotes cannot be referred to by names from other scopes. <...> Moreover, except as noted, a name declared at block scope (6.3.3) has no linkage. <...> лямбды по идее не должны иметь linkage. У нх не должо быть проблем с ODR так как линкер их в принципе не должен видеть Однако: [expr.prim.lambda.closure] The closure type for a non-generic lambda-expression with no lambda-capture has a conversion function to pointer to function with C ++ language linkage (10.5) having the same parameter and return types as the closure type’s function call operator. Тоесть походу в VisualStudio проблемы с функцией преобразования или с указателем на пустую лямбду - что там там нарушает ODR Возможно я не прав, но багрепорт завести стоит. Завдеите плиз!
🐙 Antony
Проблема не в вызове лямбды, проблемы начинаются когда начинает инстанцироваться std::function
std::function походу берёт указатель на лямбду с C++ linkage и в этот момент проблемы и начинаются
🐙 Antony
Constantine
Догадок лучше у меня нет :) Можно завтести тикет и смотреть что скажут разработчики VS
Я правильно понимаю, что вы считаете, что код, содержащий преобразование лямбды с захватом шаблонных параметров функции, соответствует действующему стандарту C++ и это не недоработка стандарта? :)
Constantine
с захватом
🐙 Antony
у нее нет имени, а значит нет linkage а раз она с захватом, то нет ещё и оператора преобразрвания к указателю на функцию c С++ linkage тоесть нарушений ODR быть не должно
Constantine
само по себе, например, инстанцирование разных шаблонных подстановок при одинаковых шаблонных параметрах не является нарушением ODR?
Constantine
мне бы пример...
Тот же самый. Возврат осуществляется как std::function, в данном случае используется ее шаблонный конструктор (причем параметром шаблона будет тип лямбда-выражения) template <typename T> inline std::function<void()> f(T * object) { return [object](){}; }
🐙 Antony
на мой взгляд всё ОК со стороны стандарта
Constantine
ладно, чиркну тогда завтра feedback to microsoft
Roman
хмм, имею две функции которые принимают анонимные функции разного типа: typedef QSharedPointer<Stream> Reference; typedef std::function<Reference ()> FunctionS; typedef std::function<void ()> FunctionV; Stream::attach(FunctionS function); Stream::attach(FunctionV function); к сожалению не работает, компилятор ругается: C2668 'Stream::attach': ambigious call to overloaded function не могу понять как разрешить ситуацию, подскажет кто?
Roman
stream->attach([this, transaction, chunkSize]() { return write( transaction->fileId, transaction->uploadProgress, chunkSize ); }) write() возвращает Reference (QSharedPointer<Stream>)
Berkus
stream->attach([this, transaction, chunkSize]() -> Reference { а так?
Roman
stream->attach([this, transaction, chunkSize]() -> Reference { а так?
оу, долгое время работаю с ламбдой, первый раз вижу подобную конструкцию, круто, снова что-то выучил, спасибо!
Surreal
оу, долгое время работаю с ламбдой, первый раз вижу подобную конструкцию, круто, снова что-то выучил, спасибо!
Такое еще с функциями, возвращающими auto, работает. Особенно в 11 стандарте, где еще не было дедакшена.
Roman
Неужели помогло?
хммм, чёт нет, не хочет
Roman
C2668: ambigious call to overloaded function по прежнему
Arseny
https://stackoverflow.com/questions/22146749/overload-resolution-with-stdfunction
Arseny
Если коротко, то std::function разрешается "отбросить" возвращаемый тип. И обе функции можно сконвертировать в std::fuction<void()>
Александр
только там не возвращаемый, а принимаемый, не?
Roman
т.е. эта пропблема решена в C++14 ?
Arseny
Это не проблема, это фича.
Surreal
только там не возвращаемый, а принимаемый, не?
Возвращаемый std::function<Reference ()>
Arseny
В C++14 хотя бы гарантируется SFINAE при конвертации в std::function
Александр
Возвращаемый std::function<Reference ()>
я про ссылку на SO. там std::function<void()> и std::function<void(int)>