我不确定我是否理解为什么第一个测试结果为真,第二个结果为假。我知道来自 typeid().name()
的信息通常不可靠,但我的主要问题在于 typeid
本身。我不明白为什么 *test
的类型不是 Location<1>
,或者还有什么问题。有什么想法吗?在这里我看不到的类型是否有相同的包装器?提前致谢,如果答案显而易见,我们深表歉意。
#include <iostream>
#include <utility>
#include <typeinfo>
class LocationAbstract
{
virtual void get_() = 0;
};
template<int i>
class Location : public LocationAbstract
{
public:
static constexpr int test = i;
virtual void get_() override
{
return;
}
};
template <int i>
Location<i> LocationGenerator()
{
Location<i> test{};
return test;
}
int main()
{
LocationAbstract *table[10];
table[0] = new decltype(LocationGenerator<0>());
table[1] = new decltype(LocationGenerator<1>());
Location<1> *test;
try
{
std::cout << "Casting\n";
test = dynamic_cast<Location<1>*>(table[1]);
}
catch (std::bad_cast &e)
{
std::cout << "Bad cast\n";
}
// test1, evaluates to true
std::cout << (typeid(*test) == typeid(*dynamic_cast<Location<1>*>(table[1]))) << "\n";
std::cout << typeid(*test).name() << "\n";
std::cout << typeid(*dynamic_cast<Location<1>*>(table[1])).name() << "\n----\n";
// test2, why does this evaluate to false while the above evaluates to true ?
std::cout << (typeid(Location<1>()) == typeid(*dynamic_cast<Location<1>*>(table[1]))) << "\n";
std::cout << typeid((Location<1>())).name() << "\n";
std::cout << typeid(*dynamic_cast<Location<1>*>(table[1])).name() << "\n";
auto test1 = Location<1>();
auto test2 = *dynamic_cast<Location<1>*>(table[1]);
std::cout << typeid(test1).name() << " and " << typeid(test2).name() << "\n";
return 0;
}
答案 0 :(得分:3)
额外的一组 ()
在这里变得与众不同。在 typeid(Location<1>())
和 typeid((Location<1>()))
中,Location<1>()
实际上意味着两个完全不同的东西。
在 typeid(Location<1>())
中,Location<1>()
被解释为返回 Location<1>
且不带参数的函数类型。
在 typeid((Location<1>()))
中,Location<1>()
被解释为对匿名 Location<1>
对象进行值初始化。
typeid
运算符可用于类型或表达式。也就是说,您可以说 typeid(int)
和 typeid(42)
。由于 Location<1>()
可以 被解释为一种类型,因此该语言是这样做的。 (Location<1>())
不能解释为类型,所以它必须解释为表达式。作为表达式的一部分,Location<1>()
的唯一含义是对匿名 Location<1>
对象进行值初始化,因此 typeid
为您提供该对象的类型。
让这成为创建临时对象时更喜欢统一初始化语法的另一个原因; Location<1>{}
不会有这种歧义。
答案 1 :(得分:1)
检查这两行:
std::cout << (typeid(Location<1>()) == typeid(*dynamic_cast<Location<1>*>(table[1]))) << "\n";
std::cout << typeid((Location<1>())).name() << "\n";
在第一行中,您使用 typeid(Location<1>())
。 typeid
可以接受类型也可以接受表达式,Location<1>()
是一种没有参数的函数类型,返回类型为 Location<1>
。
那为什么打印出来的名字是一样的呢?那是因为第二行:typeid((Location<1>()))
。通过将参数括在括号中,它不再是有效类型,因此将其视为表达式并打印 typeid(Location<1>)
的名称。删除额外的括号会在相同的修改方案下打印 F8LocationILi1EEvE
。
为了避免歧义,您也可以直接使用类型(typeid(Location<1>)
)或使用大括号:typeid(Location<1>{})
)。