use*_*112 5 c++ metaprogramming c++17
我在编译时有一个用char数组表示的字段的逗号分隔列表:
constexpr static char arrayStr[] = "a,b,c";
我想对“,”进行拆分,并在编译时获得可用的元素数量。伪代码:
constexpr static size_t numFields = SPLIT(arrayStr, ",");
将返回3。
有什么方法可以使用C ++ 17来实现吗?
使用通过引用接受固定长度数组的模板化函数,根据数组的长度进行模板化:
#include <iostream>
#include <array>
constexpr char arrayStr[] = "a,b,c";
template<size_t N>
constexpr size_t numFields(const char(&arrayStr)[N], char delim) {
size_t count = 1;
for (const auto& ch : arrayStr) {
if (ch == delim) {
++count;
}
}
return count;
}
using namespace std;
int main(int argc, char *argv[]) {
array<string,numFields(arrayStr,',')> x;
cout << x.size() << endl;
}
Run Code Online (Sandbox Code Playgroud)
将箭头 arrayStr 模板化为固定大小的数组参数,允许基于范围的 for 循环。
编辑
OP在评论中询问有关在编译时创建一个类的问题,该类的成员包括字符串文字及其标记化计数(还提到了有关静态类成员的内容,但我不清楚用例)。这更棘手!经过一些工作,上面的numFields函数可以与这样的东西一起使用:
class Foo {
public:
template<typename T>
constexpr Foo(T&& str, char delim)
: _array(std::forward<T>(str)),
_count(numFields(_array,delim)) {
}
auto data() const {
return _array;
}
size_t size() const {
return _count;
}
private:
const char (&_array)[N];
const size_t _count;
};
template<typename T>
constexpr auto wrapArray(T&& str, char delim) -> Foo<sizeof(str)> {
return Foo<sizeof(str)>(std::forward<T>(str),delim);
}
constexpr auto wrappedArrayStr = wrapArray("a,b,c",',');
using namespace std;
int main(int argc, char *argv[]) {
cout << wrappedArrayStr.size() << endl;
cout << wrappedArrayStr.data() << endl;
}
Run Code Online (Sandbox Code Playgroud)
我不确定这里的完美转发是否必要,但我用它来将字符串文字参数转发给类成员。辅助函数wrapArray可以防止必须双重粘贴所有编译时字符串文字,即避免constexpr Foo<sizeof("a,b,c")> wrappedArrayStr("a,b,c",',');.