Catch2中生成1024个随机值的std::array报错,如何解决?
Catch2中生成std::array随机值生成器的编译错误解决
问题描述
尝试在Catch2中实现生成包含1024个随机值的std::array生成器,编写代码如下:
#include "catch2/catch_all.hpp" #include <array> #include <vector> TEST_CASE("Foo") { auto s = GENERATE(as<std::array<char, 1024>>{}, 'a'); REQUIRE(!s.empty()); }
编译时触发错误:
In file included from /opt/compiler-explorer/libs/catch2/v3.0.0-preview3/src/catch2/generators/catch_generators_all.hpp:25, from /opt/compiler-explorer/libs/catch2/v3.0.0-preview3/src/catch2/catch_all.hpp:46, from <source>:1: /opt/compiler-explorer/libs/catch2/v3.0.0-preview3/src/catch2/generators/catch_generators.hpp: In instantiation of 'Catch::Generators::Generators<T> Catch::Generators::makeGenerators(as<T>, U&&, Gs&& ...) [with T = std::array<char, 1024>; U = char; Gs = {}]': <source>:7:14: required from here /opt/compiler-explorer/libs/catch2/v3.0.0-preview3/src/catch2/generators/catch_generators.hpp:181:39: error: array must be initialized with a brace-enclosed initializer 181 | return makeGenerators( value( T( std::forward<U>( val ) ) ), std::forward<Gs>( moreGenerators )... ); |
错误原因
std::array是C++聚合类型,无法通过单参数构造函数(如std::array<char,1024>('a'))初始化,必须使用花括号初始化器。而Catch2的GENERATE在as<T>模式下,会尝试直接用传入的单个字符构造std::array,这违反了聚合类型的初始化规则,导致编译错误。
解决方法
方式1:生成随机值填充的std::array
使用Catch2的generate生成器,结合C++随机数工具构造随机数组:
#include "catch2/catch_all.hpp" #include <array> #include <random> TEST_CASE("Foo") { auto s = GENERATE( as<std::array<char, 1024>>{}, generate([]() { std::array<char, 1024> arr; std::random_device rd; std::mt19937 gen(rd()); // 可根据需求调整随机范围 std::uniform_int_distribution<char> dist('a', 'z'); for (auto& elem : arr) { elem = dist(gen); } return arr; }) ); REQUIRE(!s.empty()); }
方式2:生成固定值填充的std::array
如果需要构造全为某个固定值的数组,先初始化好数组再传入GENERATE:
#include "catch2/catch_all.hpp" #include <array> #include <algorithm> TEST_CASE("Foo") { std::array<char, 1024> fixed_arr; std::fill(fixed_arr.begin(), fixed_arr.end(), 'a'); auto s = GENERATE(as<std::array<char, 1024>>{}, fixed_arr); REQUIRE(!s.empty()); }
关键提示
- Catch2的
GENERATE宏中,as<T>后的参数要么是符合T初始化规则的对象,要么是Catch2支持的生成器(如generate、values)。 - 对于聚合类型(如
std::array、自定义结构体),必须遵循C++聚合初始化规则,避免用单参数构造的方式初始化。
内容的提问来源于stack exchange,提问作者getsoubl
相关产品推荐
相关产品推荐

