T *t; //T is an implementation detail
t = new T; //want to avoid naming T to allow for flexibility
t = new decltype(*t); //error: cannot use 'new' to allocate a reference
t = new std::remove_reference<decltype(*t)>::type(); //clunky
This answers why decltype(*t)
returns T &
and not T
.
I can put my last line into a macro, but that seems suboptimal. Is there a better solution than what I have so far? Does this belong on Code Review?
auto is a keyword in C++11 and later that is used for automatic type deduction. The decltype type specifier yields the type of a specified expression. Unlike auto that deduces types based on values being assigned to the variable, decltype deduces the type from an expression passed to it.
decltype is a compile time evaluation (like sizeof ), and so can only use the static type.
decltype(auto) is primarily useful for deducing the return type of forwarding functions and similar wrappers, where you want the type to exactly “track” some expression you're invoking.
If they're on the same line, you can use auto
to only name T
once:
auto t = new T;
Otherwise, you could create a small function template:
template <class T>
void do_new(T * &p) {
p = new T;
}
// Usage:
int main()
{
T *t;
do_new(t);
}
As @MadScienceDreams pointed out, you can extend this to allow non-default constructors:
template <class T, class... Arg>
void do_new(T * &p, Arg &&... arg) {
p = new T(std::forward<Arg>(arg)...);
}
// Usage:
int main()
{
T *t;
do_new(t);
std::string *s;
do_new(s, "Abc");
}
std::remove_pointer<decltype(t)>::type
is more expressive/clear.
You can also use a local typedef
if this is repeated several times, or would make a certain line grow excessively long/complicated.
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