有没有办法将预编译器列表与 C++ 宏合并/连接起来?
Is there a way to merge / concatenate precompiler lists with C++ macros?
我有两个列表:
#define LIST1 {1, 2, 3}
#define LIST2 {4, 5, 6}
并使用 C++ 宏我想写这样的东西:
// Obviously doesn't work
#define MERGE LIST1 ## LIST2
int my_array[] = MERGE;
产生:
int my_array[] = {1, 2, 3, 4, 5, 6};
在编译时。
这样的事情可能吗?还有其他关于字符串的问题,但是我终究无法弄清楚如何使用非字符串数组声明来做到这一点。
编辑:
我当然更愿意不使用宏,并且希望列表格式也有所不同。不幸的是,包含这些列表定义的头文件不是我可以编辑的文件。
除非别无选择,否则不要使用宏,最好使用模板。
它们是类型安全的。
例如,您可以创建编译时评估函数 (constexpr)
合并两个列表(数组)和 returns 一个数组。
#include <array>
// type_t is the type held by the array (an int in this example)
// N = size of first array
// M = size of second array
// const type_t(&arr)[N] is the syntax for passing an array by const reference
template<typename type_t, std::size_t N, std::size_t M>
constexpr auto merge(const type_t(&arr1)[N], const type_t(&arr2)[M])
{
std::array<type_t, N + M> arr{}; // this initialization is needed in constexpr
std::size_t index{ 0 };
for (const auto& value : arr1) arr[index++] = value;
for (const auto& value : arr2) arr[index++] = value;
return arr;
}
int main()
{
constexpr auto arr = merge({ 1,2,3 }, { 4,5,6 });
constexpr auto strings = merge( {"abc", "def" }, {"ijk", "lmn"} );
// static_assert is like assert, but evaluated at compile time.
static_assert(arr.size() == 6);
static_assert(arr[4] == 5);
return 0;
}
只需稍微重述您的代码即可轻松实现:
#define LIST1 1, 2, 3
#define LIST2 4, 5, 6
#define MERGE LIST1, LIST2
int my_array[] = { MERGE };
#include <iostream>
int main() {
for(auto const& x : my_array) {
std::cout << x << "\n";
}
}
我有两个列表:
#define LIST1 {1, 2, 3}
#define LIST2 {4, 5, 6}
并使用 C++ 宏我想写这样的东西:
// Obviously doesn't work
#define MERGE LIST1 ## LIST2
int my_array[] = MERGE;
产生:
int my_array[] = {1, 2, 3, 4, 5, 6};
在编译时。
这样的事情可能吗?还有其他关于字符串的问题,但是我终究无法弄清楚如何使用非字符串数组声明来做到这一点。
编辑: 我当然更愿意不使用宏,并且希望列表格式也有所不同。不幸的是,包含这些列表定义的头文件不是我可以编辑的文件。
除非别无选择,否则不要使用宏,最好使用模板。 它们是类型安全的。
例如,您可以创建编译时评估函数 (constexpr) 合并两个列表(数组)和 returns 一个数组。
#include <array>
// type_t is the type held by the array (an int in this example)
// N = size of first array
// M = size of second array
// const type_t(&arr)[N] is the syntax for passing an array by const reference
template<typename type_t, std::size_t N, std::size_t M>
constexpr auto merge(const type_t(&arr1)[N], const type_t(&arr2)[M])
{
std::array<type_t, N + M> arr{}; // this initialization is needed in constexpr
std::size_t index{ 0 };
for (const auto& value : arr1) arr[index++] = value;
for (const auto& value : arr2) arr[index++] = value;
return arr;
}
int main()
{
constexpr auto arr = merge({ 1,2,3 }, { 4,5,6 });
constexpr auto strings = merge( {"abc", "def" }, {"ijk", "lmn"} );
// static_assert is like assert, but evaluated at compile time.
static_assert(arr.size() == 6);
static_assert(arr[4] == 5);
return 0;
}
只需稍微重述您的代码即可轻松实现:
#define LIST1 1, 2, 3
#define LIST2 4, 5, 6
#define MERGE LIST1, LIST2
int my_array[] = { MERGE };
#include <iostream>
int main() {
for(auto const& x : my_array) {
std::cout << x << "\n";
}
}