c++函数在宏值上切换语句或数组抽象
C++ function switch statement or array abstract over macro values
考虑以下代码:
#define VAL_A 0
#define VAL_B 1
#define VAL_C 2
void TestSwitch01(uint32 val)
{
printf("%u: ", op);
switch (val)
{
case VAL_A: printf("aaan"); break;
case VAL_B: printf("bbbn"); break;
case VAL_C: printf("cccn"); break;
default: printf("dddn");
}
}
#define VAL_A 10
#define VAL_B 11
#define VAL_C 12
void TestSwitch02(uint32 op)
{
printf("%u: ", op);
switch (val)
{
case VAL_A: printf("aaan"); break;
case VAL_B: printf("bbbn"); break;
case VAL_C: printf("cccn"); break;
default: printf("dddn");
}
}
在这个例子中,我有三个VAL_*
宏和两个TestSwitch*()
函数。然而,假设我有这种模式,但有5000个VAL_*
宏和20个TestSwitch*()
函数(换句话说- 20个不同版本的VAL_A
- 0,10等)。此外,我在单独的文件中有#define
…所以foo001.h
有(0 12)个VAL
's, foo002.h
有(10 11 12)个VAL
's。
我不想复制粘贴函数的20个版本,因为它是同一个函数。所以我真的想写一个抽象于宏之上的函数。
显然,我可以使用变量,但我不想这样做,因为变量将在运行时设置,这会很慢。我想写c++代码,让编译器生成20个版本的TestSwitch*()
,每个版本对应于20个不同的5000个VAL*
宏集之一。
我想避免写一个宏伪函数,因为你不能进入其中,而且它很难阅读(语法高亮和智能感知也不起作用)。
我考虑使用模板函数,但是有5000个VAL_*
宏,这将是相当疯狂的…template void <uint32 VAL_A, uint32 VAL_B ... VAL_4999> TestSwitch(...)
.
我还试图通过用函数指针数组替换switch()
语句来做到这一点(到printf()
's)…但是,在填充数组时,我仍然有复制粘贴代码的问题。
我觉得c++有工具来做我想做的事情,但我不确定如何…什么好主意吗?
基本上我想生成20个函数TestSwitchXX()
的副本-每组5000个VAL_*
一个。
也许有一些技巧使用多个文件和#include
和#if
?
一个合适的c++解决方案是取消#define
s并在结构体中使用枚举:
struct Foo {
enum { VAL_A = 0, VAL_B = 1, VAL_C = 2 };
};
struct Bar {
enum { VAL_A = 10, VAL_B = 11, VAL_C = 12 };
};
template<typename T>
void TestSwitch(int op)
{
std::cout << op << ": ";
switch (op) {
case T::VAL_A: std::cout << "aaan"; break;
case T::VAL_B: std::cout << "bbbn"; break;
case T::VAL_C: std::cout << "cccn"; break;
default: break;
}
}
演示:http://ideone.com/u3kTtF
你也可以用enum class
代替struct
,但是你只能有值,struct选项让你有机会包含其他描述T
的东西的值,这些值以后可能会有用。
枚举类Demo: http://ideone.com/DBZuyn
XMacros -他们是趋势…让我看看……对啊,2001 .
在:
行"generate_testswitch.h"#define IMPLEMENT_TEST_SWITCH(N) void TestSwitch#N(uint32 val)
{
printf("%u: ", op);
switch (val)
{
case VAL_A: printf("aaan"); break;
case VAL_B: printf("bbbn"); break;
case VAL_C: printf("cccn"); break;
default: printf("dddn");
}
}
"testswitch1.c"// you may isolate these in yet another header
#define VAL_A 0
#define VAL_B 1
#define VAL_C 2
#include "generate_testswitch.h"
IMPLEMENT_TEST_SWITCH(01)
我考虑使用模板函数,但是有5000个
VAL_*
宏,这将是相当疯狂的…template void <uint32 VAL_A, uint32 VAL_B ... VAL_4999> TestSwitch(...)
.
对于您将问题标记为c++
,我认为可以使用标准的最新版本(或至少c++ 11)。
正因为如此,不,使用模板并不是很疯狂。
您可以使用可变模板做类似的事情:
template<typename T, T... V>
void TestSwitch(uint32_t val) {
// ...
}
因此你可以这样调用它:
TestSwitch<int, 10, 11, 12>(42);
我不清楚你想对这些值做什么,所以很难说函数体必须如何编写。
作为一个简单的例子,它遵循一个实现,检查val
是否包含在V...
中:
template<typename T, T... V>
void TestSwitch(uint32_t val) {
bool found = false;
int arr[] = { 0, (found = found || (val == V), 0 )... };
(void)arr;
std::cout << "found: " << found << std::endl;
}
其他问题可能需要一个空的递归等等。
只要你处理范围,你也可以这样做:
#include <cstddef>
#include <functional>
#include <iostream>
template<std::size_t B, std::size_t... I>
void TestSwitch(uint32_t val, std::index_sequence<I...>) {
bool found = false;
int arr[] = { 0, (found = found || (val == (B+I)), 0 )... };
(void)arr;
std::cout << "found: " << found << std::endl;
}
template<std::size_t B, std::size_t N>
void TestSwitch(uint32_t val) {
TestSwitch<B>(val, std::make_index_sequence<N>{});
}
int main() {
TestSwitch<40, 3>(42);
TestSwitch<40, 3>(0);
}
在本例中,我们使用基数(即起始值)和范围长度调用TestSwitch
,然后我们依靠std::make_index_sequence
和另外一个函数来生成范围本身并完成工作。
- 比较if语句中的数组值和int值
- 为什么我的 if else 语句不起作用并从数组中输出正确的索引?
- 任意大小的 constexpr 数组是否可以用作 switch 语句中的案例?
- 有人可以解释一下吗?这是关于数组和数组内部 if 语句的一些处理
- 在编译时自动生成用于稀疏数组索引的switch语句
- C++ 将二维数组索引与条件语句中的函数值进行比较
- 如果带有字符数组的语句无法正常工作
- 如何在Char数组中搜索Char在IF条件语句中
- 使用 if (? 运算符) 语句传递带有指针的数组
- C 搜索数组以获取一个数字,但如果找不到该数组,则不会触发其他语句
- If/Else 语句在 2D 数组中移动时出现问题
- 显示使用函数、switch 语句和多维数组的程序的多个不合逻辑的错误
- 2D数组-将三个元素与if语句进行比较
- visual在C++中的if语句中的数组中使用特定值
- for 语句内的动态数组
- 如何使用嵌套的 if 语句检查字符数组
- 无法弄清楚为什么我的程序在条件不为真时执行 if 语句(数组)
- 正在尝试使用if语句检查数组数据
- 如何在不使用if语句的情况下查找数组中的最大值和最小值
- 将字符串存储在要在 IF 语句中使用的数组中的可能方法