Reputation: 337
I am trying to check whether each parameter within a parameter pack can be stored within 8 bytes (sizeof <= 8)
I have the function signature:
template <typename Return, typename... Arguments>
inline auto invoke(std::uint64_t hash, Arguments... arguments) -> Return
Using fold expressions, I have tried:
static_assert((sizeof(arguments) <= 8 && ...));
Which failed to compile with unexpected token '...', expected 'expression'
- I assume it's invalid or incorrect?
Using C++20 concepts and constraints, I assume something along the lines of is possible?
template <typename Return, typename... Arguments> requires (sizeof(arguments) <= 8 || ...)
inline auto invoke(std::uint64_t hash, Arguments... arguments) -> Return
I assume there is a way of using the standard library to say check that a type fits within a std::uint64_t
say also?
Upvotes: 1
Views: 495
Reputation: 1594
Try this way:
#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;
}
Using the comma operator and the initializer_list to do the trick.
With C++17, we can further trim the code to:
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)), ...);
}
taking the advantage of fold expressions.
I do not understand the downvotes, but as this is my last post in stackoverflow, I uploaded a live example at wandbox: https://wandbox.org/permlink/NZbqpRaTs2TFOCwG
Upvotes: -2
Reputation: 23527
With C++20 concepts, there are many ways how to achieve the desired behavior. For instance:
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
}
Live demo: https://wandbox.org/permlink/Q9tifNVplsx9BjGN
Another option is your solution:
template <typename... Types> requires ((sizeof(Types) <= 8) && ...)
void f() { }
Or, e.g.:
template <typename... Types> requires (std::max({ sizeof(Types)... }) <= 8)
void f() { }
Upvotes: 3