typeid( " " ) != typeid(const char*)
typeid("") != typeid(const char*)
我正在制作一个C++库,它严重依赖RTTI(到另一种语言的可自定义桥接),并且对字符串文字类型非常困惑。
这是我为显示问题而进行的简单测试:
std::cout << typeid(const char*).name() << std::endl; // PKc
std::cout << std::any("").type().name() << std::endl; // PKc
std::cout << typeid("").name() << std::endl; // A1_c
对我来说,看起来像前两个打印const char*
的类型,但最后一个是一个数组。
为什么std::any("").type()
和typeid("")
的结果不同?有没有办法获得第一个行为,即使字符串文字的结果一致(我使用类型标识来调用不同的类型处理程序)?
PS:测试是在 Ubuntu 19.04 上使用 Clang 版本 8.0.0-3(标签/RELEASE_800/final)完成的。
正如其他人所提到的,字符串文字""
的类型是const char[1]
,如解释的那样,例如,C++中字符串文字的数据类型是什么?
存储在std::any("")
中的类型const char*
,因为您使用的是以下构造函数 (http://www.eel.is/c++draft/any.cons#8):
// Effects: Constructs an object of type any that contains an object of
// type std::decay_t<T> direct-initialized with std::forward<T>(value).
template< class T>
any( T&& value );
在这种情况下,T
是const char(&)[1]
(字符串文字""
的类型),因此std::decay_t<const char(&)[1]>
会给你const char*
,这就是为什么std::any("").type()
的typeid()
是const char*
的类型ID。
为什么
std::any("").type()
和typeid("")
的结果不同?
参考以下参考:
template< class ValueType > any( ValueType&& value );
4)构造一个初始内容为
std::decay_t<ValueType>
类型的对象,从std::forward<ValueType>(value)
直接初始化。
std::decay_t<const char[1]>
const char*
.
以下是FrankHB1989在 isocpp.org 论坛上的引述,我认为在这个问题的背景下,这与理解std::any
有关:
[
std::any
] 甚至不是"任何对象"。正如我之前所论证的,我预计单词"any"是"任何一类对象类型"(即 cv 非限定非数组对象类型)的缩写,但std::any
对值类型进行了额外的改进 CopyConstructible,因此它实际上是针对"任何可复制的 cv 非限定非数组对象类型"。
因此
有没有办法获得第一个行为,即使字符串文字的结果保持一致(我使用类型标识来调用不同的类型处理程序)?
没有办法有数组的std::any
(你可以有std::array
的std::any
,但字符串文字不是std::array
),也没有办法使typeid("")
成为一个指针。但是,您可以使用std::decay_t<decltype("")>
获取与存储在std::any
中相同的类型。
字符串文本的类型为const char*
是一个常见的误解。
其实不然。它具有类型const char[<size + 1>]
(加上一个用于空终止符)。
例如""
有类型const char[1]
.
但是我们经常将字符串文字分配给const char*
,这是不合惯例的(也是因为否则我们会触发导致复制字符串的特殊规则)。
此外,数组名称衰减规则实际上使得很难在 C 中观察名称的数组性(以及扩展的 C++);std::any
的工作方式就是一个例子。