c++ 11编译时组合两个字符串的最简单方法

Simplest way to combine two strings at compile time with C++11

本文关键字:两个 字符串 方法 最简单 编译 组合 c++      更新时间:2023-10-16

我正在尝试连接两个编译时间字符串:

constexpr const char* getString1() { return "abababa"; };
constexpr const char* getString2() { return "lalalal"; };
constexpr const char* getString3() { return getString1() + getString2(); }; //wont compile

有一个现代的,简单的方法在c++中做到这一点吗?

这是使用std::applyC++17解决方案。

注意:我使用autorequires将其推入C++20

这实际上可以通过利用std::applyconstexpr这一事实来实现,这意味着您可以根据其底层参数包访问和元组类型,包括数组:

#include <tuple>
#include <array>
#include <iostream>
//helper function:
//create array without the last element provided
//used to remove '' in concat
template <std::size_t N>
constexpr std::array<const char, N> trim(
    auto head, auto... chars
) requires (sizeof...(chars) == N) {
    if constexpr (sizeof...(chars) == 0) {
        return std::array<const char, 0>{}; //ignore last element
    } else {
        return std::apply([&head](auto... trim_chars){
            return std::array<const char, N>{head, trim_chars...}; //recurse
        }, trim<N - 1>(chars...));
    }
}
//concatonate 2 arrays by converting them into param backs using std::apply
//this works because std::apply is a constexpr function
template <std::size_t N, std::size_t M>
constexpr std::array<const char, N + M + 1> concat(
    const std::array<const char, N + 1>& n,
    const std::array<const char, M + 1>& m
) {
    std::array<const char, N> trim_n = std::apply([](auto... args){return trim<N>(args...);}, n);
    return std::apply([&](auto... n_chars){
        return std::apply([&](auto... m_chars){
            return std::array<const char, N + M + 1>{n_chars..., m_chars...};
        }, m);
    }, trim_n);
}
//example strings
constexpr std::array<const char, 4> x{"abc"};
constexpr std::array<const char, 4> y{"def"};
constexpr std::array<const char, 7> z = concat<3, 3>(x, y);
int main() {
    std::cout << &x[0] << " + " << &y[0] << " = " << &z[0];
}
这个输出:

abc + def = abcdef

有一个现代的,简单的方法在c++中做到这一点吗?

最后的答案是:

实际上在编译时使用constexpr函数无法做到这一点。

 return getString1() + getString2();

将尝试添加两个指针,这对编译器来说是没有意义的。

任何其他尝试都需要检查实际的字符字面量以进行连接(例如strcat()),这在编译时是无法完成的。

可用的替代方法是使用注释中指出的宏。


也许有人能做一些黑巫术模板魔法,但我怀疑它是否值得付出努力。