Не лучше использовать std::declval
объявленные в форме:Т declval() вместо T && declval() для common_type
template< class T > T declval(); // (1)
тогда текущий:
template< class T > T && declval(); // (2)
для std::common_type
(возможно, с другим именем только для этой текущей цели)?
Поведения common_type
использования (1)
ближе к поведению тройного оператора (но не с помощьюstd::decay_t
), чем поведение при использовании (2)
:
Каковы недостатки этого подхода? Верно ли, что для (1)
в decltype()
тип контекста T
должен быть конструктивным (вообще-то должен иметь хотя бы один конструктор) и/или разрушаемым?
Reference article сказал:
Для неспециализированной станд :: common_type, правила для определения общего типа между каждой парой Т1, Т2 точно правила для определения типа возвращаемого тройного условного оператора в unevaluated context, с произвольным первым аргументом типа bool и с
xvalues of type T1 and T2 (since C++17)
std::declval<T1>() and std::declval<T2>() (until C++17)
в качестве второго и третьего операндов.The common type is the result of std::decay applied to the type of the ternary conditional (since C++14).
Я думаю, что это весьма вероятно, последнее предложение (emphasized
) должен быть не только since C++14
, но и until C++17
быть справедливым. В противном случае 1-е предложение цитирования не будет выполнено даже после C++ 17 и будет обнаружен некоторый дефект.
В should-stdcommon-type-use-stddecay есть некоторые пояснения относительно проблем std::common_type
, но это только справочная информация по текущему вопросу.
Для начала это прерывается, если тип имеет удаленный деструктор или не может быть возвращен из функции (например, абстрактные типы, типы массивов, типы функций). –
@ T.C. Я думаю, что для этих типов * тернарный оператор * из текущей реализации по умолчанию 'std :: common_type' также не имеет смысла, но специализации. – Orient
@ T.C. На самом деле нам просто нужна функция языка, которая «дает мне выражение типа' T' » – Barry