static_assert参数包中每个参数的大小

时间:2018-12-12 05:34:15

标签: c++ c++17 c++20

我正在尝试检查参数包中的每个参数是否可以存储在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 个答案:

答案 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