I don't understand why the following code compiles with Clang++, but not with g++.
#include <memory>
class A {
public:
virtual ~A() {}
};
class B : public A {
public:
virtual ~B() {}
};
template <typename Base, typename T>
inline bool isInstanceOf(const T& object) {
// This line compiles with clang++ (7.0.1) and with gcc (8.3.1)
// return std::is_same<Base, T>::value ? true : (dynamic_cast<const Base*>(&object) != nullptr);
// This line compiles only with clang++
return std::is_same<Base, T>::value || dynamic_cast<const Base*>(&object) != nullptr;
}
int main() {
isInstanceOf<A>(B());
isInstanceOf<A>(A()); // Compilation fails
return 0;
}
The compilation error:
$> g++ -o bin -Wall -Werror test.cpp
test.cpp: In instantiation of 'bool isInstanceOf(const T&) [with Base = A; T = A]':
test.cpp:24:24: required from here
test.cpp:19:79: error: the compiler can assume that the address of 'object' will never be NULL [-Werror=address]
std::is_same<Base, T>::value || dynamic_cast<const Base*>(&object) != nullptr;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~
cc1plus: all warnings being treated as errors
Why the template instanciation don't skip the second part of the test?
The following code also compiles:
if (std::is_same<Base, T>::value) {
return true;
} else {
return dynamic_cast<const Base*>(&object) != nullptr;
}
The compilation of the following code fails too:
if (std::is_same<Base, T>::value) {
return true;
}
return dynamic_cast<const Base*>(&object) != nullptr;
Aucun commentaire:
Enregistrer un commentaire