我正在尝试检查参数包中的每个参数是否可以存储在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
,也可以说吗?
答案 0 :(得分:3)
使用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() { }
答案 1 :(得分:-2)
尝试这种方式:
#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