我的用例如下。给定一个对象,我想要一种可读的方法来确定该对象是否是另一个对象的子类。显然,核心是对 dynamic_cast
的调用,但我想要更具可读性的东西。所以我有以下内容:
template <typename C, typename T>
bool isInstanceOf(const T& t) noexcept {
if (typeid(t) == typeid(C)) {
return true;
}
if (dynamic_cast<const C*>(&t) != nullptr) {
return true;
}
return false;
}
这按预期工作,但如果我在 C 和 T 实际上是同一类型的地方进行调用,我会在 dynamic_cast 上收到编译器警告,因为编译器知道它永远不会返回 null。这引出了我的问题:如果 C 和 T 实际上是同一类型,我可以编写一个专门的版本来简单地返回 true 吗?
我尝试了显而易见的
template <typename C>
inline bool isInstanceOf(const C& t) noexcept {
return true;
}
但这给了我一个错误“调用'isInstanceOf'是不明确的。”
这并不是真正的高优先级项目,因为我实际上永远不会调用 isInstanceOf<B>(b)
我知道 b 是 B 类型,但我在单元测试中有它的完整性,想看看是否有办法让编译器在不发出警告的情况下优化它。
如果有帮助,这是我收到的警告消息:
In file included from Tests/rtti.cpp:15:0:
.build/Linux-x86_64/include/kss/util/rtti.hpp: In instantiation of ‘bool kss::util::rtti::isInstanceOf(const T&) [with C = {anonymous}::B; T = {anonymous}::B]’:
Tests/rtti.cpp:81:9: required from here
.build/Linux-x86_64/include/kss/util/rtti.hpp:61:40: warning: the compiler can assume that the address of ‘t’ will never be NULL [-Waddress]
if (dynamic_cast<const C*>(&t) != nullptr) {
~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~
最佳答案
如果你有 C++17,你可以使用 if constexpr
:
template <typename C, typename T>
bool isInstanceOf(const T& t) noexcept {
if constexpr (std::is_same<T, C>::value) {
return true;
} else {
return dynamic_cast<const C*>(&t) != nullptr;
}
}
在 C++17 之前,重载和 SFINAE(或标记分派(dispatch))可能会完成这项工作:
template <typename C>
bool isInstanceOf(const C& t) noexcept {
return true;
}
template <typename C, typename T>
std::enable_if_t<!std::is_same<C, T>::value, bool>
isInstanceOf(const T& t) noexcept {
return dynamic_cast<const C*>(&t) != nullptr;
}
关于c++ - 当两种类型相同时专门化 c++ 模板函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55446422/