【发布时间】: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::byte与std::byte完全相同,就像它的底层类型一样,允许别名。所以没有ub。 -
@geza 我想你误会了。我说的不是你应该使用
std::byte,而是你的mylib::byte可以使用别名;-p -
@Swordfish:
std::byte允许使用别名,因为标准 这么说,而不是因为它使用unsigned char作为其基础类型。该标准在任何地方都对char和unsigned char给予豁免,它也对std::byte给予豁免。不是“任何以它们为基础类型的枚举”,而是std::byte特别是。