static_assert размер каждого параметра в пакете параметров - PullRequest
0 голосов
/ 12 декабря 2018

Я пытаюсь проверить, можно ли сохранить каждый параметр в пакете параметров в пределах 8 байт (sizeof <= 8) </p>

У меня есть сигнатура функции:

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 ]

0 голосов
/ 12 декабря 2018

Попробуйте следующим образом:

#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)), ...);
}

с использованием выражений складывания.


Я не понимаю отрицательных голосов, но так как это мой последний пост в stackoverflow, я загрузил живой пример на wandbox: https://wandbox.org/permlink/NZbqpRaTs2TFOCwG

0 голосов
/ 12 декабря 2018

С концепциями 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() { }
...