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("")
的结果不同?有没有办法获得第一个行为,即使字符串文字的结果一致(我使用类型识别来调用不同的类型处理程序)?
P.S.: 测试是在 Ubuntu 19.04.
上使用 Clang 版本 8.0.0-3 (tags/RELEASE_800/final) 完成的
正如其他人所提到的,字符串文字 ""
的类型是 const char[1]
,如 What is the datatype of string literal in 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
Why do results for std::any("").type()
and typeid("")
differ?
根据以下reference:
template< class ValueType >
any( ValueType&& value );
4) Constructs an object with initial content an object of type std::decay_t<ValueType>
, direct-initialized from std::forward<ValueType>(value)
.
std::decay_t<const char[1]>
是 const char*
.
这是 FrankHB1989 关于 isocpp.org forum 的引述,我认为这与理解 std::any
有关,在这个问题的上下文中:
[std::any
] is even not for "any object". As I have argued before, I have expect the word "any" being short for "any first-class object type" (i.e. cv-unqualified non-array object type), but std::any
has additional refinement of CopyConstructible on the value type, so it is actually for "any copyable cv-unqualified non-array object type" instead.
如此
Is there a way to get first behavior, i.e. make results for string literals consistent (I use type identification to call different type handlers)?
没有办法得到数组的 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++)中观察名称的 array-ness 非常困难; std::any
的工作方式就是一个例子。
我正在制作一个 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("")
的结果不同?有没有办法获得第一个行为,即使字符串文字的结果一致(我使用类型识别来调用不同的类型处理程序)?
P.S.: 测试是在 Ubuntu 19.04.
上使用 Clang 版本 8.0.0-3 (tags/RELEASE_800/final) 完成的正如其他人所提到的,字符串文字 ""
的类型是 const char[1]
,如 What is the datatype of string literal in 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*
.
Why do results for
std::any("").type()
andtypeid("")
differ?
根据以下reference:
template< class ValueType > any( ValueType&& value );
4) Constructs an object with initial content an object of type
std::decay_t<ValueType>
, direct-initialized fromstd::forward<ValueType>(value)
.
std::decay_t<const char[1]>
是 const char*
.
这是 FrankHB1989 关于 isocpp.org forum 的引述,我认为这与理解 std::any
有关,在这个问题的上下文中:
[
std::any
] is even not for "any object". As I have argued before, I have expect the word "any" being short for "any first-class object type" (i.e. cv-unqualified non-array object type), butstd::any
has additional refinement of CopyConstructible on the value type, so it is actually for "any copyable cv-unqualified non-array object type" instead.
如此
Is there a way to get first behavior, i.e. make results for string literals consistent (I use type identification to call different type handlers)?
没有办法得到数组的 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++)中观察名称的 array-ness 非常困难; std::any
的工作方式就是一个例子。