我想要使用一些常量@PostMapping("/setPermissions")
public HttpStatus setPermissions(..) {
return HttpStatus.OK
}
值,所以我使用#define。
问题是我得到了一些这样的定义名称:
int
代码中有没有办法以某种方式迭代它们以使用字符串构造其名称,然后获取构造字符串的定义值?我的意思是伪代码:
#define a1 123
#define a2 6543
#define a3 12
...
我已经习惯了C#,所以我遇到了一些习惯c ++的问题。定义真的是最合适的方法吗?
答案 0 :(得分:3)
以#
开头的行由预处理器评估 - 编译器不会看到它们,只看到它们的效果。因此,C ++代码不能与预处理器变量交互,因为在编译代码时它们不再存在。
常量可以这样定义,但C ++提供了更好的方法。例如,它们可以包装在名称空间中以避免名称冲突。
//auto lets the compiler deduce the type for you
auto const my_var = 4.5; //double
auto const close_to_pi = 3.4f; //float
auto const the_answer = 42; //int
auto const kibibyte = 1024u; //unsigned int
要获得有关定义后缀类型的更多说明,请查看integer literals和floating point literals。当您更熟悉C ++以探索编译时常量表达式时,您可能还希望稍后阅读constexpr。
答案 1 :(得分:2)
代码中有没有办法以某种方式迭代它们用字符串构造它们的名字,然后得到构造字符串的定义值?
不,使用定义无法做到这一点。
您需要将值放入某个容器中才能迭代这些值。
如果您只想存储值,可以使用std :: vector。
如果您想同时拥有名称和值,可以使用std :: map。类似的东西:
#include <iostream>
#include <string>
#include <map>
#define a0 42
#define a1 5
#define a2 15
#define a3 25
int main() {
// Define the map
std::map<std::string, int> m;
// Intialize the map
m["a0"] = a0;
m["a1"] = a1;
m["a2"] = a2;
m["a3"] = a3;
// Access map using name
for(size_t i =0 ; i < m.size(); i++)
{
std::string name = "a" + std::to_string(i);
std::cout << m[name] << std::endl;
}
// Iterate all map elements
for (auto& x : m)
{
std::cout << x.first << ":" << x.second << std::endl;
}
return 0;
}
答案 2 :(得分:2)
另一种方法是生成一些包含你想要的C ++文件。因此,您需要为此目的设置build。您经常使用一些build automation工具(例如GNU make,ninja等等),您可以将其配置为在需要时生成一些C ++文件(例如,添加几行如果您使用make
,则为Makefile
。生成一些C ++代码的程序可以是一些脚本(例如shell,awk,Python,Guile,...),一些专门的元程序(例如{{ 1}}用于Qt程序),其他一些预处理器,如GPP或m4,或者你自己的其他C ++程序等......这种元编程方法通常与C ++和C一起使用世纪(查看Qt moc,bison,SWIG,......举例说明。)
另请参阅this相关问题的答案(使用C)。
你会生成一些包含像
这样的东西的标题moc
(您不希望在#define a1 123
#define a2 6543
#define a3 12
- s)
=
或者您可能会生成一些#define
之类的
enum
请注意,在运行时生成C ++代码可能比其他(例如enum number_en {
a1= 123,
a2= 6543,
a3= 12,
};
based)方法更有效(自构建时)解决方案。
答案 3 :(得分:1)
宏由预处理器解析,处理器不知道(您不能在代码中使用它们)。
如果要将名称与值关联,可以使用const map和constexpr表达式:
constexpr std::string a1="a1";
constexpr std::string a2="a2";
constexpr std::string a3="a3";
const std::map<std::string, int> = {
{a1, 123},
{a2, 6543},
{a3, 12}
}
您需要C ++ 11(或更高版本)才能实现此目的。
答案 4 :(得分:1)
首选const变量超过MACRO
constexpr auto a1 = 123;
constexpr auto a2 = 6543;
constexpr auto a3 = 12;
然后迭代它们,不需要名称,只需执行
for (auto e : {a1, a2, a3}) {
func(e);
}
您可能希望为列表创建一个变量,以避免在多个位置迭代时重复。