我正在制作一个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 (标记/Release800/final)完成的。
发布于 2019-06-12 14:23:03
正如其他人所提到的,字符串文本""的类型是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*,这就是为什么std::any("").type()的typeid()是const char*的类型ID。
发布于 2019-06-12 14:24:08
为什么
std::any("").type()和typeid("")的结果不同?
根据以下参考文献
template<类ValueType > any( ValueType&& value ); 4)构造具有初始内容的对象--
std::decay_t<ValueType>类型的对象,直接从std::forward<ValueType>(value)初始化.
std::decay_t<const char[1]>是const char*。
以下是FrankHB1989 on isocpp.org论坛的引用,我认为在这个问题的上下文中,这与理解std::any有关:
std::any甚至不适用于“任何对象”。正如我之前所指出的,我期望单词"any“是”任何头等对象类型“(即cv-不限定的非数组对象类型)的缩写,但是std::any对值类型有更多的CopyConstructible细化,因此它实际上是针对”任何可复制的cv-不限定的非数组对象类型“。
正因如此
是否有一种获得第一行为的方法,即使字符串文本的结果保持一致(我使用类型标识来调用不同类型的处理程序)?
没有办法拥有数组的std::any (可以有std::any of std::array,但字符串文字不是std::array),也没有办法使typeid("")成为指针。但是,您可以使用std::decay_t<decltype("")>获取与存储在std::any中的相同类型。
发布于 2019-06-12 14:26:05
字符串文字具有const char*类型是一种常见的误解。
它没有,它有const char[<size + 1>]类型(加上null终止符的一个)。
例如,""有const char[1]类型。
但是,我们通常将字符串文本分配给const char*,这是不符合约定的(另外也是因为我们触发了导致复制字符串的特殊规则)。
此外,数组名称衰减规则实际上使得很难在C中观察名称的数组性(扩展为C++);std::any的工作方式就是一个例子。
https://stackoverflow.com/questions/56564321
复制相似问题