Мне нужно знать, когда происходит продвижение по службе, и что это такое. Мое предположение
template <typename T>
struct promoted { using type = std::common_type_t<T, T>; };
template <typename T>
using promoted_t = typename promoted<T>::type;
Очевидно, это сломается, если пользователь начнет переопределять версии std::common_type
, Предполагая, что этого не произойдет, это будет работать? Предполагается, что условный оператор применяет акции до дальнейшей оценки. Я думаю, что-то подобное должно быть в Стандарте когда-нибудь.
Если вам интересно, почему я этого хочу, то это для varargs уровня C:
auto r = va_arg( the_va_list, T );
Если я изначально передал тип, который преобразуется при использовании в Varargs, как float
превращается в double
s, я должен положить в исходный тип для T
или изуродованный тип? В случае, если это последнее, я делаю тип черт для этого, который нуждается в промоушене на последнем шаге.
Грубо говоря, bool ? T : T
делает T
, Ничто не продвигается в этом выражении.
Передача не POD (или действительно, любого определенного пользователем) типа в списке переменных аргумента в стиле C вызывает неопределенное поведение.
Например, MSC помещает копию структуры в стек без вызова конструктора (если он определен).
Например:
struct thing
{
int v;
// Not called
operator int() const throw()
{return this->v;}
thing(int v) throw() :
v(v)
{}
// Also not called
thing(const thing &other) throw() :
v(other.v)
{}
};
void frob(...)
{
}
int main(int argc, const char **argv)
{
thing t(47);
frob(t); // <- rep stosd/q here, but this is really UD
return 0;
}
РЕДАКТИРОВАТЬ:
Для пояснения: невозможно использовать шаблоны для обнаружения того, что что-то передается в список переменных аргументов в стиле C, так как не определено, что компилятор делает с пользовательскими типами в таких ситуациях.
Других решений пока нет …