当前位置: 首页 > 知识库问答 >
问题:

可以为字符串文字创建模板化的用户定义文字(文字后缀)吗?

楚昀
2023-03-14

当我发现可以将用户定义的文字模板化时,我大吃一惊:

template <char ...C> std::string operator ""_s()
{
    char arr[]{C...};
    return arr;
}

// ...

std::cout << 123_s;

但是上面的声明不适用于字符串文字:

"123"_s

给我以下错误:

掠夺。cpp:在函数“int main()”中:
prog。cpp:12:15:错误:调用“运算符”“s()”时没有匹配的函数
std::cout

prog.cpp:4:34:注意:候选:模板标准::字符串运算符" " _s()
模板标准::字符串运算符" " _s()

prog.cpp: 4:34:注意:模板参数推导/替换失败:

(意念)

有没有一种方法可以将模板化的用户定义文字和字符串文字一起使用?

共有2个答案

呼延才
2023-03-14

在C 20之前,在标准C中是不可能的。请参阅@T.C.的答案,了解适用于GCC和Clang的非标准解决方案。

从 C 20 开始,可以将字符串文本作为模板参数传递。你需要一个像这样的帮助程序类:

#include <algorithm>
#include <cstddef>
#include <string_view>

namespace impl
{
    // Does nothing, but causes an error if called from a `consteval` function.
    inline void ExpectedNullTerminatedArray() {}
}

// A string that can be used as a template parameter.
template <std::size_t N>
struct ConstString
{
    char str[N]{};

    static constexpr std::size_t size = N - 1;

    [[nodiscard]] std::string_view view() const
    {
        return {str, str + size};
    }

    consteval ConstString() {}
    consteval ConstString(const char (&new_str)[N])
    {
        if (new_str[N-1] != '\0')
            impl::ExpectedNullTerminatedArray();
        std::copy_n(new_str, size, str);
    }
};

它允许您这样做:

#include <iostream>

template <ConstString S>
void Print()
{
    std::cout << S.view() << '\n';
}

int main()
{
    Print<"foo">();
}

这对于您的用例来说可能就足够了,并且您可能不需要模板 UDL 本身。

但是如果你真的需要它们,这是可能的:

#include <iostream>

template <ConstString S>
void operator""_print()
{
    std::cout << S.view();
}

int main()
{
    "foo"_print;
}
年高洁
2023-03-14

Clang和GCC支持一个扩展,允许你做

template<class CharT, CharT... Cs>
std::string operator ""_s() { return {Cs...}; }

但是标准C中什么都没有;标准化它的建议已经提出了几次,每次都被拒绝,最近一次是在不到一个月前,主要是因为模板参数包是一种非常低效的字符串表示方式。

 类似资料:
  • 问题内容: 假设我有一个自定义类,该类实现/重写了一些方法: 现在,我现在必须通过在构造函数中传递一个字符串来手动创建的实例: 这还不错,但是它导致了这样的想法,即使用类似于or或or的自定义字符串前缀会很酷。 是否有可能在Python中创建/注册这样的自定义字符串文字前缀,以使文字产生新的实例? 还是将这些前缀硬编码到Python解释器中? 问题答案: 这些前缀在解释器中进行了硬编码,您不能注册

  • 链接: https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/es6/create-strings-using-template-literals 问题:< br >使用带反斜杠的模板文字语法创建列表元素(li)字符串数组。每个列表元素的文本应该是result对象的failure属性中的数组元素之一

  • 问题内容: 我有以下Ecma-Script-6代码 输出如下: 和 我已经能够在此处将字符串串联起来,那么使用模板文字的情形将是什么? 问题答案: 如果像问题示例中那样仅将模板文字与占位符(例如)一起使用,则结果与串联字符串相同。从主观上讲,它看起来更好并且更易于阅读,尤其是对于多行字符串或包含这两者的字符串,因为您不必再​​转义那些字符了。 可读性是一个很棒的功能,但是关于模板最有趣的是Tagg

  • 问题内容: 在此结构定义中: 字符串 “ json:message” 的含义是什么,以及如何访问它(如果可访问)。先感谢您。 问题答案: 这些是结构标记。包使用此struct标记 将对象转换为JSON,并将 JSON字符串转换为对象 在将一个结构封送(编码)为JSON字符串时,它将查找此struct标记以分配 键名,如果不存在,则它可能会使用结构字段名本身 顺便说一句语法是错误的 这是供参考的示例

  • 问题内容: 在ES6中使用字符串连接或模板文字时,HTML代码生成在现代浏览器中运行的速度是否可测得更快? 例如: 字符串串联 模板文字 问题答案: 目前看来,字符串连接速度更快:http : //jsperf.com/es6-string-literals-vs-string-concatenation 我测试过的是在#enable-javascript-harmony启用了该标志的V4 4.3

  • 当我有一个字符串需要将一个字符连接到它的结尾时,我应该更喜欢超过是否有任何性能原因? 我知道数组字符串连接和字符串生成器,我并不是在询问一般情况下如何连接字符串的建议。 我也知道有些人会有冲动向我解释过早的优化,而且一般来说我不应该为这些小事情费心,请不要... 我之所以问这个问题,是因为从编码风格的偏好来看,我更倾向于使用后一个,但我觉得第一个应该表现得稍微好一点,因为知道所附加的只是一个字符,