C ++ 17在逗号上拆分constexpr字符串,并且在编译时有多少个元素?

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来实现吗?

jwi*_*ley 1

使用通过引用接受固定长度数组的模板化函数,根据数组的长度进行模板化:

#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",',');.