Комментарии 14
Концепты еще не готовы к использованию
+1
Скопирую сюда сниппет, о котором идёт речь. Или godbolt.org.
Выглядит как довольно специфичный баг компилятора: нужно, чтобы шаблон без ограничения инстанциировался до того, как будет объявлен шаблон с ограничением, такое в своей практике видел один или два раза. Обычно есть условный .hpp, где все шаблоны объявляются, и есть .h/.cpp, где инстанциируются и используются шаблоны из .hpp.
Конечно, досадно, что не всё работает так, как надо, но это всего лишь 1-5% случаев.
template <class> void foo() {} //1
void useFirst()
{
foo<void>();// call 1 - instantiate "void foo<int>()"
}
template <class> void foo() requires true {} //2
void useSecond()
{
foo<void>();// call 2 - instantiate "void foo<int>() requires true"
}
// error example: definition with same mangled name '_Z3fooIvEvv' as another definition
Выглядит как довольно специфичный баг компилятора: нужно, чтобы шаблон без ограничения инстанциировался до того, как будет объявлен шаблон с ограничением, такое в своей практике видел один или два раза. Обычно есть условный .hpp, где все шаблоны объявляются, и есть .h/.cpp, где инстанциируются и используются шаблоны из .hpp.
Конечно, досадно, что не всё работает так, как надо, но это всего лишь 1-5% случаев.
0
DELETED
0
мне вот интересно, если взять с++17/с++20 реализации того же pair из доклада Андрея (ссылка в статье), и сравнить, то какие цифры получатся? Там ведь весь нюанс именно в том, что реализация с концептами получается сильно проще, с меньшим числом прокси-классов
0
Спасибо за идею, обязательно проверим.
Пока что могу сказать, что основываясь на сравнении с optional (тоже один из примеров в статье Андрея), вариант с trailing requires clause работает значительно медленнее классической реализации с использованием прокси/базовых классов. Но, как уже обещал, обязательно проверю отдельно pair в следующей статье по концептам.
Пока что могу сказать, что основываясь на сравнении с optional (тоже один из примеров в статье Андрея), вариант с trailing requires clause работает значительно медленнее классической реализации с использованием прокси/базовых классов. Но, как уже обещал, обязательно проверю отдельно pair в следующей статье по концептам.
0
Мне кажется работает быстрее просто потому что в случае со специализациями программист вручную делает работу компилятора по инстанцированию шаблона. И хотелось бы сразу прививать хорошие код стайлы — когда концепт называется не IsBig, как будто это type trait или consteval функция, а Big, потому что речь идёт о самом типе. Это просто логично(как по мне).
+ хотелось бы увидеть в сравнении msvc, или он настолько плох, что даже в сравнение не идёт?))
И последнее — смотрел ваш доклад по концептам(по нему узнавал как вообще ими пользоваться), хотелось бы спросить, есть ли какая то разница между
и попытками вызвать конструктор вместо каста? Вообще по логике вещей касты должны быть более жестким требованием, т.к. сами требуют возможности конструктора внутри своего требования. Но…
+ хотелось бы увидеть в сравнении msvc, или он настолько плох, что даже в сравнение не идёт?))
И последнее — смотрел ваш доклад по концептам(по нему узнавал как вообще ими пользоваться), хотелось бы спросить, есть ли какая то разница между
View post on imgur.com
и попытками вызвать конструктор вместо каста? Вообще по логике вещей касты должны быть более жестким требованием, т.к. сами требуют возможности конструктора внутри своего требования. Но…
0
С одной стороны да, мы довольно много подсказали компилятору сами. С другой стороны мы написали довольно много кода, который компилятору нужно прочитать, к тому же добавили несколько enable_if, наследований, которые необходимо обработать и т.д. Так что тут, вроде, более выигрышным выглядит вариант с концептами. Сложно ответить «почему», не зная деталей реализации, но мы попытались)
Про концепты — соглашусь. Логичнее было бы Big, однако в угоду старых привычек назвал IsBig, каюсь, грешен:)
Касаемо msvc: его отсутствие никак не связано с ужасными/отличными результатами. Дело в том, что уже порядка трёх лет не компилируюсь msvc, вот он и не пришёл на ум сразу (компилируюсь, что не удивительно, gcc/clang на Ubuntu). А когда большую часть замеров выполнил, то пришёл к выводу, что будет справедливо сравнивать gcc/clang выполняемые на Ubuntu (WSL) с msvc на Windows (Host). Так что пока только gcc/clang. Думаю, msvc стоит протестировать обособленно, или, может, с тем же clang, но уже на windows.
Прошу прощения, не заметил дополнения с вопросом про
В данном примере, на мой взгляд, разницы между static_cast и вызовом конструктора нет. (Откуда пример, кстати?)
Уточните, пожалуйста, что вы понимаете под более/менее жестким требованием?
Про концепты — соглашусь. Логичнее было бы Big, однако в угоду старых привычек назвал IsBig, каюсь, грешен:)
Касаемо msvc: его отсутствие никак не связано с ужасными/отличными результатами. Дело в том, что уже порядка трёх лет не компилируюсь msvc, вот он и не пришёл на ум сразу (компилируюсь, что не удивительно, gcc/clang на Ubuntu). А когда большую часть замеров выполнил, то пришёл к выводу, что будет справедливо сравнивать gcc/clang выполняемые на Ubuntu (WSL) с msvc на Windows (Host). Так что пока только gcc/clang. Думаю, msvc стоит протестировать обособленно, или, может, с тем же clang, но уже на windows.
Прошу прощения, не заметил дополнения с вопросом про
signed_integral
.В данном примере, на мой взгляд, разницы между static_cast и вызовом конструктора нет. (Откуда пример, кстати?)
Уточните, пожалуйста, что вы понимаете под более/менее жестким требованием?
0
Пример из стандартной библиотеки в реализации msvc. Насчёт 1 пункта думаю компиляторы уже давно по особому обрабатывают enable if, буквально как языковую единицу, а не «инстанцировать структурку че та там делать ...» как делается это в общем виде.
А под более жестким требованием я понимаю то как обрабатываются концепты в С++20, делятся на булевы констранты или как они там и по логике булевых операций определяется какая допустим перегрузка более строгая — boolA или boolA&&boolB (тут вторая) boolA или boolA || boolB (тут первая).
В случае с static_cast/конструктор это не так очевидно и не делится на логические единицы, но по логике человеческой возможность кастить что либо является более строгим требованием, потому что оно включает в себя требование существования конструктора
А под более жестким требованием я понимаю то как обрабатываются концепты в С++20, делятся на булевы констранты или как они там и по логике булевых операций определяется какая допустим перегрузка более строгая — boolA или boolA&&boolB (тут вторая) boolA или boolA || boolB (тут первая).
В случае с static_cast/конструктор это не так очевидно и не делится на логические единицы, но по логике человеческой возможность кастить что либо является более строгим требованием, потому что оно включает в себя требование существования конструктора
0
Если именно применительно к концептам, то для компилятора разницы между вариантом со static_cast и вариантом с конструктором нет. Иными словами:
template<typename T>
concept SignedIntegral_v1 = std::integral<T> && T(-1) < T(0);
template<typename T>
concept SignedIntegral_v2 = std::integral<T> && static_cast<T>(-1) < static_cast<T>(0);
void foo(SignedIntegral_v1 auto const &) {}
void foo(SignedIntegral_v2 auto const &) {}
void later() {
foo(int32_t { 1 }); // call of overloaded 'foo(int)' is ambiguous
}
0
У вас кажется опечатки
template typename T
void foo(IsBig auto const &) { }
template typename T ???What im doing here???
void foo(auto const &) {}
0
И все-таки 50-100 миллисекунд это совсем немного для компиляции файла. В реальных проектах некоторые файлы и по 5 секунд компилируются. Интересно было бы посмотреть прогресс на таких объемах. Мало ли там например сложность каких-то алгоритмов не линейная. Да и includ-ы на файл подключаются всего один раз
0
Согласен, но если использовать "настоящие файлы", то невозможно отследить влияние той или иной конструкции на компиляцию. Было решено для начала посмотреть на одиночные, они же синтетические, варианты, а затем протестировать что-то из реальной жизни. Например, вариант библиотеки из C++17 VS он же, но из C++20.
0
Зарегистрируйтесь на Хабре , чтобы оставить комментарий
Производительность компилятора при работе с концептами в C++20