【问题标题】:Is it possible to create a user defined literal, which converts string literals to an array of own-type?是否可以创建一个用户定义的文字,将字符串文字转换为自己类型的数组?
【发布时间】:2018-09-09 13:53:09
【问题描述】:

是否可以创建一个用户定义的文字,将字符串文字转换为自己类型的数组?

假设我有一个自己的字节类型,mylib::byte:

namespace mylib {
    enum class byte: unsigned char { };
}

因此,例如,"Hello"_X 应该具有 mylib::byte[5] 类型,其值为 { 'H', 'e', 'l', 'l', 'o' }


这里是背景,所以也许你可以推荐一些其他的解决方案。

我有一个 utf-8 类,它存储一个 mylib::byte * 和一个长度(这类似于 std::string_view,它不拥有内存区域):

namespace mylib {
    class utf8 {
        const byte *m_string;
        int m_length;
    };
}

我希望能够方便地在代码中使用字符串文字构造mylib::utf8,如下所示:

mylib::utf8 u = "Hello";

目前我使用reinterpret_cast,也就是UB:

namespace mylib {
    class utf8 {
        const byte *m_string;
        int m_length;

    public:
        utf8(const byte *s) {
            m_string = s;
            m_length = ...;
        }
        utf8(const char *s) {
            m_string = reinterpret_cast<const byte *>(s); // causes UB afterwards
            m_length = ...;
        }
    };
}

所以我想,我想要这样的东西,以避免 UB:

mylib::utf8 u = "Hello"_X; // I'd like to have the constructor with `const byte *` to be called here

注意:mylib::byte 是强制性的,我无法更改。

【问题讨论】:

  • "m_string = reinterpret_cast(s); // 之后导致 UB" 为什么是这个 ub?
  • 数组是不可复制的,你不能按值返回一个。您也许可以返回 std::array - 但它是临时的,任何指向它的指针很快就会变得悬空。
  • @geza your mylib::bytestd::byte 完全相同,就像它的底层类型一样,允许别名。所以没有ub。
  • @geza 我想你误会了。我说的不是你应该使用std::byte,而是你的mylib::byte 可以使用别名;-p
  • @Swordfish: std::byte 允许使用别名,因为标准 这么说,而不是因为它使用 unsigned char 作为其基础类型。该标准在任何地方都对charunsigned char 给予豁免,它也对std::byte 给予豁免。不是“任何以它们为基础类型的枚举”,而是std::byte 特别是

标签: c++ c++17 c++20


【解决方案1】:
mylib::utf8 operator "" _X(const char* c, std::size_t n) {
  auto* r = new mylib::byte[n];
  std::transform(c, c+n, r, [](auto c){ return (mylib::byte)(unsigned char)(c););
  return {r,n};
}

这符合您所写的所有标准;你没有要求零泄漏。

【讨论】:

  • “程序启动时”应该是“每当调用operator "" _X”/“每当评估""_X 文字时”,不应该吗?
  • 谢谢,有趣的想法。不过,我不确定这个:“在程序启动时只会有一些”。不是这样吗,每次程序到达时都会调用operator "" _X 吗?我的意思是,对于for (int i=0; i&lt;100; i++) "Hello"_X;,它被调用了 100 次,不是吗?
  • @geza 嗯。是的,我想错了。让它成为现实(一旦保证)很难。
猜你喜欢
  • 2011-12-29
  • 2017-04-16
  • 2013-11-27
  • 1970-01-01
  • 2021-08-10
  • 1970-01-01
  • 2021-01-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多