My ultimate goal is to compare the type stored within std::shared_ptr with another type (in this testcase this type is int)
int main() {
std::shared_ptr<int> shared_ptr_to_int;
std::cout << typeid(int).name() << std::endl;
std::cout << typeid(decltype(*shared_ptr_to_int)).name() << std::endl;
if (std::is_same<decltype(*shared_ptr_to_int), int>::value) {
std::cout << "is same!\n";
}
else {
std::cout << "not the same!\n";
}
}
For my test case I am getting the result "not the same".
i
i
not the same!
When "dereferencing" a std::shared_ptr — through std::shared_ptr<...>::operator* — the result is a reference, this means that decltype(*shared_ptr_to_int) is equivalent to int&.
A reference-to-int and int is not the same type, and as such you get the behavior which you are describing.
A dereferenced std::shared_ptr yields a reference so that one can actually reach in and modify the object that the shared_ptr is currently handling.
In order to fix your example you should use std::remove_reference to strip away that (potentially unexpected) reference.
if (std::is_same<std::remove_reference<decltype(*shared_ptr_to_int)>::type, int>::value) {
...
}
You could also pass shared_ptr_to_int as the operand of decltype and then use the result as qualifier to reach into element_type:
if (std::is_same<decltype(shared_ptr_to_int)::element_type, int>::value) {
...
}
typeid(...).name() return the same name for both?When typeid is invoked with a type which is a reference it will discard this and treat the operand as if it was a non-reference type (ie. it will simply throw away the &).
Something else worth mentioning is that the result from invoking typeid(...).name() is implementation-defined — one should never put too much trust into the returned value. The function might even return the same name for completely distinct types — there are literally no guarantees (from the standard's point of view).
Further reading:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With