Мой пример использования следующий. Для данного объекта мне нужны читабельные средства определения, является ли этот объект подклассом другого объекта. Очевидно, что в основе лежит вызов 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, потому что компилятор знает, что он никогда не вернет ноль. Это подводит меня к моему вопросу: могу ли я написать специализированную версию этого, которая просто возвращает true, если C и T на самом деле одного типа.
Я попробовал очевидное
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) {
~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~