static_assert размер каждого параметра в пакете параметров
Я пытаюсь проверить, можно ли сохранить каждый параметр в пакете параметров в пределах 8 байт (sizeof <= 8)
У меня есть функция подписи:
template <typename Return, typename... Arguments>
inline auto invoke(std::uint64_t hash, Arguments... arguments) -> Return
Используя выражения сгиба, я попытался:
static_assert((sizeof(arguments) <= 8 && ...));
Который не удалось скомпилировать с unexpected token '...', expected 'expression'
- Я полагаю, это неверно или неправильно?
Используя концепции и ограничения C++20, я предполагаю, что что-то подобное возможно?
template <typename Return, typename... Arguments> requires (sizeof(arguments) <= 8 || ...)
inline auto invoke(std::uint64_t hash, Arguments... arguments) -> Return
Я предполагаю, что есть способ использовать стандартную библиотеку, чтобы проверить, что тип вписывается в std::uint64_t
сказать тоже?
2 ответа
С концепциями C++20 есть много способов достичь желаемого поведения. Например:
template <typename T, size_t N>
concept bool SizeLessEqual = sizeof(T) <= N;
template <SizeLessEqual<8>... Types>
void f() { }
int main() {
f<bool, char, int, double>();
f<std::string>(); // error
}
Демонстрационная версия: https://wandbox.org/permlink/Q9tifNVplsx9BjGN
Другой вариант - ваше решение:
template <typename... Types> requires ((sizeof(Types) <= 8) && ...)
void f() { }
Или, например:
template <typename... Types> requires (std::max({ sizeof(Types)... }) <= 8)
void f() { }
Попробуйте так:
#include <cstdint>
#include <utility>
template <typename... Arguments>
auto invoke(std::uint64_t hash, Arguments... arguments)
{
auto check = []( auto&& argument )
{
static_assert( sizeof(argument) <= 8, "size too large" );
return 0;
};
auto dummy = { 0, ( check(std::forward<Arguments>(arguments)), 0) ... };
return 0;
}
int main()
{
invoke( 0UL, '1' );
invoke( 0UL, '1', 2 );
invoke( 0UL, '1', 2, 3UL );
//invoke( 0UL, '1', 2, 3UL, static_cast<long double>(1.0) );
return 0;
}
Использование оператора запятой и initializer_list, чтобы сделать трюк.
С C++17 мы можем дополнительно урезать код до:
template <typename... Arguments>
auto invoke(std::uint64_t hash, Arguments... arguments)
{
auto check = []( auto&& argument )
{
static_assert( sizeof(argument) <= 8, "size too large" );
};
(check(std::forward<Arguments>(arguments)), ...);
}
пользуясь выражениями сгиба.
Я не понимаю отрицательных голосов, но так как это мой последний пост в stackru, я загрузил живой пример на wandbox: https://wandbox.org/permlink/NZbqpRaTs2TFOCwG