You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++20中能否通过宏传参实现constexpr函数返回含静态数组的类型元组?

问题:将宏参数的无引号字符串字面量转为constexpr环境可访问的唯一类型字符串

需要将宏参数传入的无引号字符串字面量,转换为可在constexpr环境中访问的字符串(支持前缀拼接),优先实现为带static constexpr array<char, N>的唯一类型(例如模板A<1>,其中A<1>::str为对应字符串的静态constexpr数组),也可接受模板参数形式(如template<... 'h','e'...>)。


测试用例

头文件部分

#include <array>
#include <tuple>
#include <cassert>
#include <string>
#include <iostream>

待修正的演示代码

template<int I>
struct A;

template<>
struct A<0>
{
  static constexpr auto str = std::to_array("abc"); // 此处硬编码的"abc"应来自宏参数
};

template<>
struct A<1>
{
  static constexpr auto str = std::to_array("def"); // 同上
};

constexpr auto f(char const* s0, char const* s1)
{
  return std::tuple<
    A<0>, // 0使类型唯一,其静态数组应包含s0对应字符串
    A<1>  // 同理
  >{};
}

#define STR(arg) #arg
#define STRINGIFY(arg) STR(arg)

#define MEMBER(arg) STRINGIFY(arg)

不可修改的测试代码

//=====================================================================
// NOTHING BELOW THIS LINE MAY BE CHANGED.

struct C
{
  static constexpr auto x = f(
    MEMBER(abc),
    MEMBER(def)
  );
};

int main()
{
  // The type returned by f() is a tuple.
  using xt = decltype(C::x);
  
  // Each element of that tuple must be a type...
  using e0 = std::tuple_element_t<0, xt>;
  using e1 = std::tuple_element_t<1, xt>;

  // ... that defines a static constexpr array<> 'str'.
  constexpr std::array a0 = e0::str;
  constexpr std::array a1 = e1::str;
  
  std::string s0{a0.begin(), a0.end()};    // Note that the array str includes a terminating zero. 
  std::string s1{a1.begin(), a1.end()};

  std::cout << "s0 = \"" << s0 << "\"\n";
  std::cout << "s1 = \"" << s1 << "\"\n";

  // ... that has the value that was passed as macro argument.
  assert(s0.compare("abc") && s0[3] == '\0');
  assert(s1.compare("def") && s1[3] == '\0');
}

当前代码的问题

  • 字符串为硬编码,未从宏参数获取
  • f()的参数未被实际使用
  • 未满足核心需求:每个f()参数需对应返回元组中的一个唯一类型元素,该类型需包含对应宏参数的静态constexpr数组

可行解决方案代码

template<std::size_t N>
struct TemplateStringLiteral {
  std::array<char, N> chars;
  consteval TemplateStringLiteral(std::array<char, N> literal) : chars(literal) { }
};

template<TemplateStringLiteral literal>
struct B {
  static constexpr auto str = literal.chars;
};

template<TemplateStringLiteral s>
struct Wrap
{
};

template <TemplateStringLiteral s0, TemplateStringLiteral s1>
consteval auto f(Wrap<s0>, Wrap<s1>)
{
  return std::tuple<
    B<s0>,
    B<s1>
  >{};
}

#define STR(arg) #arg
#define STRINGIFY(arg) STR(arg)
#define MEMBER(arg) Wrap<std::to_array(STRINGIFY(arg))>{}

内容的提问来源于stack exchange,提问作者Carlo Wood

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 13:48:24