2013-03-08 141 views
1

说里面定义我有一堆的常量的定义命名空间内:“迭代”过常量命名空间

namespace FooConstants{ 
    const string foo1 = "foo1"; 
    const string foo2 = "foo2"; 
    //... 
    const string fooN = "fooN"; 
} 

是否有可能使用频加速至“迭代”对这些常量的名字呢?就像一个宏扩展生成foo1,foo2fooN,并让我对每个做一些事情。我相信这可以使用一些Boost库来完成,但是我找不到它。

顺便说一下,这种技术有没有一个合适的名称?

编辑:我被要求澄清这是否意味着要在编译或运行时解决。答案是编译时间:我想生成对所有常量进行操作的代码。

+0

你知道'N'吗? – Flexo 2013-03-08 21:06:30

+0

假设它是硬编码的,但我想解决一般情况(任何N值) – 2013-03-08 21:10:59

回答

2

我改变你的榜样,开始不断的编号为0,以简化逗号一代,但你绝对可以做到这一点,事情在编译时发生的事情:

#include <boost/preprocessor/cat.hpp> 
#include <boost/preprocessor/iteration/local.hpp> 
#include <boost/preprocessor/punctuation/comma_if.hpp> 
#include <utility> 
#include <string> 
#include <map> 

namespace FooConstants{ 
    const std::string foo0 = "foo0"; 
    const std::string foo1 = "foo1"; 
    const std::string foo2 = "foo2"; 
    const std::string foo3 = "fooN"; 
#define N 3 
} 

namespace metadata { 

const std::map<int, std::string> constants = { 

#define BOOST_PP_LOCAL_MACRO(n) \ 
    BOOST_PP_COMMA_IF(n) \ 
    std::make_pair(n, BOOST_PP_CAT(FooConstants::foo,n)) 

#define BOOST_PP_LOCAL_LIMITS (0, N) 

#include BOOST_PP_LOCAL_ITERATE() 
}; 
} 

int main() {} 

这里预处理器生成initalizer_list从而可以initalise a const std::map。如果你想要的话,你可以用constexpr和模板做更多的疯狂的const事情。

仅仅因为这可能并不意味着我会建议在真正的代码基础上做。

+0

看起来不错。但是,为什么你不鼓励做这样的事情呢? (因为它使代码看起来有点难看) – 2013-03-11 14:18:30

+0

@dario_ramos这是“奇怪的代码”,这意味着维护成本总是会更高。再加上我不相信这会赢得你的胜利,只需将你的常量粘贴到地图中就可以开始了,但我不认为这是我试图在愤怒中使用的东西。 – Flexo 2013-03-11 21:00:40

0

这将需要C++没有的元数据。你可以拿出一些海关宏,并使用foomax和foomin这样的会议,但没有我知道的图书馆。

+1

为什么需要元数据?这可以在编译时解决 – 2013-03-08 21:06:20

+1

@dario你的问题并没有真正说明“在每个方面做些什么”是在编译时还是在运行时发生。也许你应该澄清。 – us2012 2013-03-08 21:07:31

+0

这使用宏和约定我把这个问题的意思是在运行时这是不可能的。 – rerun 2013-03-08 22:02:08