Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 专门从事c++;两种类型相同时的模板函数_C++_Templates_Template Specialization - Fatal编程技术网

C++ 专门从事c++;两种类型相同时的模板函数

C++ 专门从事c++;两种类型相同时的模板函数,c++,templates,template-specialization,C++,Templates,Template Specialization,我的用例如下。给定一个对象,我需要一种可读的方法来确定该对象是否是另一个对象的子类。显然,其核心是调用dynamic\u cast,但我想要更具可读性的东西。因此,我有以下几点: template <typename C, typename T> bool isInstanceOf(const T& t) noexcept { if (typeid(t) == typeid(C)) { return true; } if (dynami

我的用例如下。给定一个对象,我需要一种可读的方法来确定该对象是否是另一个对象的子类。显然,其核心是调用
dynamic\u 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;
}
模板
bool isInstanceOf(常数T&T)无例外{
if(typeid(t)=typeid(C)){
返回true;
}
如果(动态施法(&t)!=nullptr){
返回true;
}
返回false;
}
这是按预期工作的,但是如果我在C和T实际上是同一类型的情况下进行调用,我会在dynamic_cast上得到一个编译器警告,因为编译器知道它永远不会返回null。这就引出了我的问题:如果C和T实际上是同一类型,我可以编写一个专门的版本来返回true吗

我试过显而易见的方法

template <typename C>
inline bool isInstanceOf(const C& t) noexcept {
    return true;
}
模板
内联布尔isInstanceOf(常数C&t)无例外{
返回true;
}
但这给了我一个错误:“调用'isInstanceOf'是不明确的。”

这并不是一个真正的高优先级项目,因为我永远不会调用
isInstanceOf(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) {
         ~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~
包含在Tests/rtti.cpp:15:0:
.build/Linux-x86_64/include/kss/util/rtti.hpp:在“bool kss::util::rtti::isInstanceOf(const T&)[与C={anonymous}::B;T={anonymous}::B]的实例化中:
测试/rtti.cpp:81:9:此处需要
.build/Linux-x86_64/include/kss/util/rtti.hpp:61:40:警告:编译器可以假定“t”的地址永远不会为NULL[-Waddress]
如果(动态施法(&t)!=nullptr){
~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~

不完全是您所要求的,主要是为了好玩,但是……下面的几个模板重载函数呢

template <typename T>
bool isIstanceOf (T const &) noexcept
 { return true; }

template <typename>
bool isIstanceOf (...) noexcept
 { return false; }

如果您有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;
    }
}
模板
bool isInstanceOf(常数T&T)无例外{
如果constexpr(std::is_same::value){
返回true;
}否则{
返回动态_cast(&t)!=nullptr;
}
}
在C++17之前,重载和SFINAE(或标记分派)可能会执行以下操作:

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;
}
模板
bool isInstanceOf(常数C&t)无例外{
返回true;
}
模板
std::如果值为,则启用,bool>
isInstanceOf(常数T&T)无例外{
返回动态_cast(&t)!=nullptr;
}

std::is_same_v
?在C++17中,没有任何SFINAE技巧是可行的。如果constexpr,只需一个
。实际上你们都可以推迟给我这个问题的答案。看起来C++14已经完全消除了我使用这个方法的需要,因为它是可转换的,并且它可以做我想做的事情。我将尝试两种方法ngs,然后将更新我的帖子。但这两个都没有检查运行时类型。谢谢@tkausl,我刚刚意识到了同样的事情。因此,看起来当我将我的库移动到C++17时,我可以做我想做的事情,但对于C++14,我可能只是在我的测试代码中抑制警告,因为代码实际上做了它应该做的事情,只是效率不如它所做的那样高同时,我可以用稍好一点的
if(std::is_base_of::value)替换
if(typeid(t)==typeid(C))
。这并没有抑制警告,但在其他一些情况下,它确实消除了对动态强制转换的需要。一个有趣的答案,但正如您所说,并不是我想要的。基本上,我需要一些东西来告诉我动态强制转换是否会成功。我也许应该记为“旁白”我主要使用它来查看测试结果。我在一个动态_转换周围有另一个包装器,我称之为“as”,它在第一次检查空指针后只返回动态_转换。我使用的远不止isInstanceOf。这非常有效,完全符合我的要求。(请注意,我必须修复您的C++14版本中的一个小语法错误。)非常感谢。我将修补我的库并在今晚重新发布。
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;
}