c++ - 当两种类型相同时专门化 c++ 模板函数

标签 c++ templates template-specialization

我的用例如下。给定一个对象,我想要一种可读的方法来确定该对象是否是另一个对象的子类。显然,核心是对 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/

相关文章:

c++ - 什么是 ?和 @ 符号在这个编译器错误中演示? - Visual Studio 2013 编译器

c++ - 具有来自不同对象的函数的函数数组

c# - 如何从配置文件重构高度重复的阅读部分

c++ - 如何为输入和输出参数使用单独的参数包?

c++ - 错误 : invalid use of incomplete type (Maybe a definition issue)

c++ - 如何检查功能模板是否已专门化?

c++ - 推力:如何有意避免将参数传递给算法?

c++ - 未声明的标识符

C++ - 如何在不重载比较运算符的情况下为 std::max 专门化自定义类型?

c++ - 可变参数模板类中需要什么前向声明?