Использование new с decltype

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

Это отвечает, почему decltype(*t) возвращает T &, а не T.

Я могу поместить свою последнюю строку в макрос, но это кажется субоптимальным. Есть ли лучшее решение, чем у меня до сих пор? Это относится к Обзор кода?

Ответы

Ответ 1

Если они находятся в одной строке, вы можете использовать auto только для названия T один раз:

auto t = new T;

В противном случае вы можете создать небольшой шаблон функции:

template <class T>
void do_new(T * &p) {
  p = new T;
}


// Usage:
int main()
{
  T *t;
  do_new(t);
}

Как указывалось в @MadScienceDreams, вы можете расширить это, чтобы разрешить конструкторы, не относящиеся к умолчанию:

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");
}

Ответ 2

std::remove_pointer<decltype(t)>::type более выразителен/ясен.

Вы также можете использовать локальный typedef, если это повторяется несколько раз или сделает определенную строку слишком длинной/сложной.