使用字符串构造定义名称

时间:2018-05-28 06:53:44

标签: c++ c++11

我想要使用一些常量@PostMapping("/setPermissions") public HttpStatus setPermissions(..) { return HttpStatus.OK } 值,所以我使用#define。

问题是我得到了一些这样的定义名称:

int

代码中有没有办法以某种方式迭代它们以使用字符串构造其名称,然后获取构造字符串的定义值?我的意思是伪代码:

#define a1  123
#define a2  6543
#define a3  12
...

我已经习惯了C#,所以我遇到了一些习惯c ++的问题。定义真的是最合适的方法吗?

5 个答案:

答案 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 literalsfloating 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 makeninja等等),您可以将其配置为在需要时生成一些C ++文件(例如,添加几行如果您使用make,则为Makefile。生成一些C ++代码的程序可以是一些脚本(例如shellawkPythonGuile,...),一些专门的元程序(例如{{ 1}}用于Qt程序),其他一些预处理器,如GPPm4,或者你自己的其他C ++程序等......这种元编程方法通常与C ++和C一起使用世纪(查看Qt mocbisonSWIG,......举例说明。)

另请参阅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);
}

您可能希望为列表创建一个变量,以避免在多个位置迭代时重复。