In the following case, decltype
always returns a reference to the type:
template <typename T>
struct MyStruct
{
};
auto getMyStruct()
{
static MyStruct<int> one;
static MyStruct<double> two;
if constexpr ((1103515245U ^ 0x1103515245) > 0x0041389155)
return &one;
else
return &two;
}
int main(int argc, char* argv[])
{
auto* p = getMyStruct();
decltype(*p); // DECLTYPE WILL ALWAYS BE REF
}
When I do decltype(*p)
, I want the type, not a type reference. std::remove_reference
can't be used, I don't know what to do.
Using decltype
with operator*
(AKA the indirection operator) indeed yields a reference type. This is because operator*
returns an "lvalue referring to the object", and decltype
yields a T&
for lvalues ("if the value category of expression is lvalue, then decltype yields T&").
But the purpose of std::remove_reference_t
is exactly to remove the reference and get the type referred to.
In your case, you can use it as following:
#include <type_traits> // required for std::remove_reference_t
// ...
std::remove_reference_t<decltype(*p)> a;
The type of a
will be MyStruct<int>
here.
Note that if the type of a
was a reference, the line above would not compile in the demo, because a reference must be initialized (and so e.g. decltype(*p) a;
would not compile).