Constantine
Потому что мы нигде std::enable_if_t<false> инстанциировать (или как это по русски) не пытаемся.
Каким образом тогда AnotherTest<Test2> выдает No, если он не получает false из is_detected, после чего проваливает enable_if_t и void_t?
Constantine
Вообще, цитата с cppreference An alias template is a template which, when specialized, is equivalent to the result of substituting the template arguments of the alias template for the template parameters in the type-id
Constantine
Ну вы утверждаете, что using-декларация для enable_if_t не эквивалентна прямой подстановке enable_if_t
Constantine
Хотя в правилах SFINAE и нет явной оговорки о том, что произойдет при провале using-декларации, но An alias template is a template which, when specialized, is equivalent to the result of substituting the template arguments of the alias template for the template parameters in the type-id
Constantine
Кажется, из этого прямо следует, что нет разницы, написано _t в using или вне его
Constantine
Ну правильно, проваливает же. Или я может вопрос не понимаю...
Собственно, проваливает и игнорирует специализацию по SFINAE
Tom
Кажется, из этого прямо следует, что нет разницы, написано _t в using или вне его
Да, мне мое утверждение тоже больше не нравится. Но тогда неясно, почему пример тот не работает.
Constantine
Да, мне мое утверждение тоже больше не нравится. Но тогда неясно, почему пример тот не работает.
Мне кажется, что это либо (а) бага вижака коих дофига в таких примерах (б) проблема из-за неиспользуемых шаблонных параметров
Constantine
Если писать через is_detected, то такие проблемы возникают категорически редко
Tom
У кого-нить есть права bug зарепортить?
Constantine
У кого-нить есть права bug зарепортить?
У меня, но я хочу чтобы они не это фиксили, а написали [a, b] = быстрее
Constantine
их человеческие ресурсы вряд ли бесконечные
Constantine
у меня все работает в проекте, разве что Intellisense фейлит примеров пять
Constantine
я лучше зарепорчу в комитет, что надо в overloaded function address operator resolution добавить ADL
Constantine
вот как жить без этого?
Constantine
https://godbolt.org/g/mPdTvW
Constantine
тебе изи, а у меня 100 строк копипасты из-за трейтов на каждый неймспейс
Constantine
вот это вообще нормально, да? template <typename T> constexpr std::enable_if_t< !sfinae::has_nonmember_equal_to_1_<T>::value && !sfinae::has_nonmember_equal_to_1_std<T>::value && !sfinae::has_nonmember_equal_to_1_utils<T>::value && !sfinae::has_nonmember_equal_to_1_atl<T>::value && sfinae::has_member_equal_to<T>::value, typename traits::member_equal_to<T>::result_type > invoke_equal_to(T const& x, T const& y) { static_assert(!traits::has_possible_bad_member_equal_to<T>(), "Please make an implicit declarion of the member == operator"); return x.operator == (y); }
Constantine
ну то есть у тебя ни один стандартный метод не вызывает ==
Constantine
или никто никогда не забывал перекрывать == в потомке?
Constantine
ну тогда либо ты пишешь на чистом С, либо у вас запрещено наследование или операторы конвенцией 😆
Constantine
А почему тогда ты уверен, что никто не забыл? :)
Constantine
Тут же очень легко - например, человек (а) наследует класс Y : Х у которого X::operator == ради type alias, человек (б) потом дописывает классу Y поле, до свидания
Constantine
человек напишет правильный тест на ==, если знает, что он нужен; при code review аналогично - нужно читать описание предка уже имеющегося класса; в статический анализ я слабо верю, хотя это весьма идейная проверка (проверить все операторы)
Constantine
вообще operator ==, имхо, одно из самых проблемных мест в С++, поскольку завязано на некоторую логическую концепцию типа неполиморфной ссылки, которая в языке отсутствует
Tom
https://godbolt.org/g/mPdTvW
А что-нить такое не поможет? https://godbolt.org/g/tvHY9t
Constantine
А что-нить такое не поможет? https://godbolt.org/g/tvHY9t
Мне нужно проверить, что не происходит конструкция вида struct A { bool operator == (A const& other) const { return true; }}; struct B : A { int x; }; bool f() { B b1 = {1}, b2 = {2}; return b1 == b2; }
Constantine
А как ADL поможет?
https://godbolt.org/g/mPdTvW
Tom
https://godbolt.org/g/mPdTvW
А как это проблему с A и B решает? чего-то мне неочевидно
Constantine
А как это проблему с A и B решает? чего-то мне неочевидно
Взятие адреса функции это ТОЧНОЕ соответствие сигнатуры
🐙 Antony
@antoshkka
Это нормально :)
Constantine
Это нормально :)
Ну то есть вам не кажется, что нужно все-таки делать ADL в такой конструкции? И не видели ли вы предложения по функциональности типа decltype, позволяющей получать адрес последней вычисляемой функции выражения?
🐙 Antony
Ну то есть вам не кажется, что нужно все-таки делать ADL в такой конструкции? И не видели ли вы предложения по функциональности типа decltype, позволяющей получать адрес последней вычисляемой функции выражения?
На первое я пару месяцев назад отвечал в этом чате, что оно не так просто как кажется: если делать ADL то это сломает текущий пользовательский код, где нужен operator== именно из текущего scope. Так что сделать тут ничего уже нельзя.
Constantine
По поводу второго - а можно пример использования?
Проверка вызываемой функции на этапе компиляции. Я могу проверить, может ли быть вызван operator ==, но совершенно никак не могу выяснить, что же за функция будет вызвана, в частности, будет ли при вызове выполнен какой-либо implicit cast
Constantine
По поводу второго - а можно пример использования?
Моя задача диагностировать следующую ошибку (аналогичная при внешнем операторе) при вызове == в обобщенном коде struct A { bool operator == (A const& other) const { return true; }}; struct B : A { int x; }; bool f() { B b1 = {1}, b2 = {2}; return b1 == b2; }
Constantine
По поводу второго - а можно пример использования?
При этом, overloaded function address resolution позволяет мне вызвать только как надо, но не выполняет ADL, мне приходится писать полностью отдельный trait для каждого namespace, в котором может быть operator ==
🐙 Antony
Может тогда лучше детектить публичное наследование?
Constantine
Может тогда лучше детектить публичное наследование?
Боюсь, много что запретим, например, std::set уж не публично ли наследуется?
Constantine
Можно было бы проверять final-класс, но опять же, std::vector не помечен как final
🐙 Antony
Давайте я в очередной раз попробую подумать пару дней, и найти решение
Constantine
Давайте я в очередной раз попробую подумать пару дней, и найти решение
Я не тороплюсь, я накопипастил там уже кода вида, хорошо хоть буста нет. template <typename T> constexpr std::enable_if_t< !sfinae::has_nonmember_equal_to_1_<T>::value && !sfinae::has_nonmember_equal_to_1_std<T>::value && !sfinae::has_nonmember_equal_to_1_utils<T>::value && !sfinae::has_nonmember_equal_to_1_atl<T>::value && sfinae::has_member_equal_to<T>::value, typename traits::member_equal_to<T>::result_type > invoke_equal_to(T const& x, T const& y) { static_assert(!traits::has_possible_bad_member_equal_to<T>(), "Please make an implicit declarion of the member == operator"); return x.operator == (y); }
Constantine
варнинга достаточно, не?
А как сделать warning?
Evgenii
А как сделать warning?
svn co http://llvm.org/svn/llvm-project/cfe/trunk clang
🐙 Antony
svn co http://llvm.org/svn/llvm-project/cfe/trunk clang
Кроме шуток. +1 за идею варнинга на подобное
Constantine
Давайте я в очередной раз попробую подумать пару дней, и найти решение
Да, наверное стоит написать еще один "всплывший момент", полагаю, это должно быть менее холиварным. У std-контейнеров нет sfinae-friendly проверок при объявлении operator ==, operator < и так далее
Evgenii
Кроме шуток. +1 за идею варнинга на подобное
я абсолютно серьезно. надо хотя бы баг открыть
Evgenii
Class B overloads A and has additional members, but doesn't overloads operator==
Constantine
к сожалению, operator в том же std будет объявлен внешним
Constantine
к сожалению, operator в том же std будет объявлен внешним
//ох уж этот ужасный стандартный русский язык, в котором общепринято операция для operator и оператор для statement
Constantine
вообще если пойти чуть дальше в логику, тут нужно что-то вроде концепции неполиморфной ссылки
Constantine
которая гарантирует, что указанный тип - в точности тот, который назван
🐙 Antony
кажется что в ближайшее время только метаклассы это починят
Constantine
кажется что в ближайшее время только метаклассы это починят
Антон, а скажите, насколько по ощущениям сырые новые модули и ждать ли их к 20 стандарту на самом деле?
Constantine
(я про модули компиляции, разумеется)
Matwey
Антон, а скажите, насколько по ощущениям сырые новые модули и ждать ли их к 20 стандарту на самом деле?
Антон, скажите, будут ли наши внуки жить при комму^W^W^W пользоваться модулями?
🐙 Antony
Мне они не кажутся сырыми, мне они кажутся сложно применимыми в текущем виде И тем не менее, в текущем виде они самые эффективные.
🐙 Antony
Если примут в текущем виде, скорее всего Boost и Стандартная библиотеки на них перейдут, пара крупных компаний для своих внутренних наработок... А остальные будут подтягиваться в течение лет 15
Constantine
У меня достаточно много кода под генератором, я не знаю ограничений, но по сути у меня ~300 TU которые исключительно потребляют шаблонный код и за счет генератора могут быть перегнаны с опреденной легкостью
Constantine
ну тут детали нужны, в чем возникают проблемы при портировании и почему нельзя раз в минуту перегонять один TU
🐙 Antony
Основная проблема - макросы. Модули их не экспоритруют. А значит не работают include guards и проблемы с import std.iostream include <iostream>
🐙 Antony
Не очень легко переходить, потребует больших телодвижений
Evgenii
собственно в этом и был спор между шлангом и майками, не?
Evgenii
include guards автоматически можно прагмой заменить
Constantine
а я не знаю, почему в стандарт не приняли #pragma once
🐙 Antony
pragma once не спасёт, она по идее тоже не экспортируется модулями
Constantine
а это не может быть просто реализовано без проблем?
Constantine
а, не может