无法创建字符串文字类型

use*_*108 6 c++ constexpr c++14

我想创建一个我可以用作模板参数的字符串文字.它将编译器抛入某种无限循环.有什么问题并修复?

template <char...> struct slit { };

template <typename ...A>
constexpr auto make_slit(char const* const s, A const ...args)
{
  return *s ? make_slit(s + 1, *s, args...) : slit<args...>();
}

int main()
{
  auto const tmp_(make_slit("slit"));

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

强制性错误(带clang++ -std=c++1y):

t.cpp:4:16: fatal error: recursive template instantiation exceeded maximum depth of 256
constexpr auto make_slit(char const* const s, A const ...args)
               ^
t.cpp:6:15: note: in instantiation of function template specialization 'make_slit<char, char, char, char, char, char, char, char, char, char, char, char, char, char, char,
      char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char,
      char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char,
      char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char,
      char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char,
      char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char,
      char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char,
      char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char,
      char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char,
      char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char, char>' requested here
  return *s ? make_slit(s + 1, *s, args...) : slit<args...>();
Run Code Online (Sandbox Code Playgroud)

Luc*_*ton 3

抛开循环实例化不谈,你无法实现你想要的,因为函数参数不能用作常量表达式,而这是模板参数所必需的。这意味着以下内容也是不允许的:

\n\n
template <typename... A>\nconstexpr auto make_slit(A const... args)\n{\n  return slit<args...>();\n}\n\n// error\nmake_slit(\'a\');\n
Run Code Online (Sandbox Code Playgroud)\n\n

如果您对此感到惊讶,请记住 constexpr 函数是一项允许某些函数在常量表达式中使用的功能。不过,你的一般是\xe2\x80\x99t:

\n\n
char c;\nstd::cin >> c;\n// what is the result type?\nmake_slit(c);\n
Run Code Online (Sandbox Code Playgroud)\n\n

然而,我应该注意,在设计文字字符串运算符期间,建议允许使用函数模板形式(很像它们用于整数和浮点文字),这将完全实现您所需要的:

\n\n
// allowed...\ntemplate<char... Cs>\nconstexpr slit<Cs...> operator"" _slit()\n{ return {}; }\n\n// ...but only for\nauto constexpr s = 123_slit;\nauto constexpr t = 12.3_slit;\n\n// ... and not\nauto constexpr u = "abc"_slit;\n
Run Code Online (Sandbox Code Playgroud)\n\n

这个缺失的功能最近在 2013 年由 Richard Smith\xe2\x80\x99s n3599: Literal Operator templates for strings提出。不幸的是我不知道该功能的当前状态是什么。

\n