LINUX.ORG.RU

Заменить SFINAE или концепты на if constexpr, почему нет?

 


1

3

Привет. Не могу понять, почему не получается заменить это:

#include <tuple>
#include <type_traits>
using namespace std;

template <typename Tuple, size_t i=0>
requires (i >= tuple_size_v<Tuple>)
consteval bool check_visitor() {
	return true;
}

template < typename Tuple, size_t i=0>
requires (i < tuple_size_v<Tuple>)
consteval bool check_visitor() {
	static_assert(! is_same_v<tuple_element_t<i, Tuple>, bool>);
	return check_visitor<Tuple, i+1>();
}

int main() {
	using T = tuple<int, double, char>;
	check_visitor<T>();
}

на это:

#include <tuple>
#include <type_traits>
using namespace std;

template < typename Tuple, size_t i=0>
consteval bool check_visitor() {
	static_assert(! is_same_v<tuple_element_t<i, Tuple>, bool>);
	if constexpr (i < tuple_size_v<Tuple>)
		return check_visitor<Tuple, i+1>();
	else
		return true;
}

int main() {
	using T = tuple<int, double, char>;
	check_visitor<T>();
}

Выражение в if constexpr зависит от параметров шаблона, как говорит справочник - в таком случае неактивная ветка должна полностью исчезнуть при инстанцировании, хоть ODR используй там необъявленное.

★★

Последнее исправление: kvpfs (всего исправлений: 4)

Опять какой-то бред с «проверками визитора». Что в лоб, что по лбу…

https://godbolt.org/z/YMjv6eedY

#include <tuple>
#include <type_traits>
using namespace std;

template <typename T>
constexpr bool check_visitor = []<auto ... I>(std::index_sequence<I...>){
    return ((!is_same_v<tuple_element_t<I, T>, bool>) && ...);
}(std::make_index_sequence<std::tuple_size_v<T>>{});

int main() {
    static_assert(check_visitor<tuple<int, double, char>>);
    //static_assert(check_visitor<tuple<int, double, bool>>); // fails
}
Siborgium ★★★★★
()
Последнее исправление: Siborgium (всего исправлений: 3)
Ответ на: комментарий от Siborgium

Спасибо, index_sequence интересная штучка, я её как-то не заметил (точнее краем уха слышал когда-то, но полезности для себя не осознал). А в своём примере сам накосячил в условии if’а, оно тоже работает

template <typename Tuple, size_t i=0>
consteval bool check_visitor() {
    if constexpr (std::tuple_size_v<Tuple> == 0)
        return true;
    else {
        static_assert(! is_same_v<tuple_element_t<i, Tuple>, bool>);
        if constexpr (std::tuple_size_v<Tuple> - i > 1)
            return check_visitor<Tuple, i+1>();
        else
            return true;
    }
}
kvpfs ★★
() автор топика
Ответ на: комментарий от ox55ff

Рекурсивно обойти типы tuple’а без SFINAE трюков и концептов. В моём случае проверяю, что типы функторов имеют допустимую сигнатуры (одну из возможных). Осматриваюсь по сторонам, ищу лаконичные способы.

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

Функтор - это стрелка из категории в категорию.

Давай расписывай где у тебя тут категории и где стрелки, дошколенок запартный.

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

Функтор - это стрелка из категории в категорию.

Ага, а линукс – это ядро. Называть функциональный объект функтором – устоявшаяся терминология.

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

Рекурсивно обойти типы tuple’а без SFINAE трюков и концептов

Нахрена их рекурсивно обходить? Простой обход не устраивает?

без SFINAE трюков и концептов

Дай дураку *** стеклянный…

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

Нахрена их рекурсивно обходить? Простой обход не устраивает?

Да, можно и просто. Это я под действием своего рекурсивного способа с if constexpr.

kvpfs ★★
() автор топика

SFINAE работает раньше и только по декларациям

constexpr позже

затягивая внутрь функции constexpr, вы убиваете SFINAE на корню

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

обойти типы tuple’а

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

кот в таких случаях лижет себе яйца, и предается романтическому настроению.

alysnix ★★★
()

Заюзывание index_sequence закончилось нахождение бага в ГЦЦ. Придётся пока рекурсивно на if constexpr.

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