如何使用 Boost 预处理器扩展字符串

How Can I Use Boost preprocessor to Expand a String

本文关键字:扩展 字符串 处理器 预处理 何使用 Boost      更新时间:2023-10-16

我想用 Boost 的预处理器库扩展一个未知长度的字符串。

例如,我想要这个:

const string foo{"bar"};

由我的宏扩展为:

foo[0], foo[1], foo[2], '\0'

这是我的代码,我主要从这里复制:

#include <boost/preprocessor/arithmetic/add.hpp>
#include <boost/preprocessor/arithmetic/inc.hpp>
#include <boost/preprocessor/arithmetic/sub.hpp>
#include <boost/preprocessor/control/deduce_d.hpp>
#include <boost/preprocessor/repetition/repeat.hpp>
#include <boost/preprocessor/tuple/elem.hpp>
#define EXPAND(first, last) BOOST_PP_REPEAT( BOOST_PP_INC( BOOST_PP_SUB((last), (first)), EXPAND_M, ((first), BOOST_DEDUCE_D())), ''
#define EXPAND_M(z, n, data) EXPAND_M_2((n), BOOST_PP_TUPLE_ELEM(2, 0, (data)), BOOST_PP_TUPLE_ELEM(2, 1, (data)))
#define EXPAND_M_2(n, first, d) foo[BOOST_PP_ADD_D((d), (n), (first))],

我可以这样使用它吗?

const string foo{"bar"};
cout << string{ EXPAND(0, foo.size()) } << endl;

由于预处理器仅适用于标记,因此您必须提供传递给foo的字符串长度作为硬编码的魔术常量,即整数文字。这是没有办法的。
由于此整数文本独立于字符串文本,因此整个方法容易出错,应避免使用。

如果您正在寻找灵活的扩展,请尝试使用可变参数模板。(很难说你应该使用什么,因为你没有提供你需要这个的用例!

您是否只是在寻找一种包含(尾随(NUL 字符的方法?

#include <algorithm>
#include <iterator>
#include <iostream>
#include <sstream>
template <typename R = std::string, size_t N>
R stringlit(char const(&lit)[N]) {
    return R(lit+0, lit+N);
}
static std::string const foo(stringlit("bar"));
static auto        const bar(stringlit<std::vector<int>>("bar"));
int main() { 
    std::cout << "foo: ";
    for(char ch : bar)
        std::cout << std::showbase << std::hex << static_cast<int>(ch) << " ";
    std::cout << "nbar: ";
    for(int i : bar)
        std::cout << std::showbase << std::hex << i << " ";
}

指纹

foo: 0x62 0x61 0x72 0 
bar: 0x62 0x61 0x72 0 

也许相关的变化:

您还可以使用模板别名来使用临时显式指定数组文本的大小:

template <typename T> using Alias = T;
static std::string const foo(stringlit(Alias<char[7]>{"bar"})); // 4 trailing ''s