2013-11-09 2 views
1

Мне нужно знать, когда состоится акция, и что это такое. Моя догадкаМожет ли быть создана специальность для продвижения по службе?

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. Предполагая, что этого не произойдет, будет ли это работать? Предполагается, что условный оператор будет применять акции до дальнейшей оценки. Я действительно думаю, что что-то подобное должно быть в Стандарте когда-нибудь.

Если вы задаетесь вопросом, почему я хочу это, это для C-уровня переменной длины:

auto r = va_arg(the_va_list, T); 

Если я первоначально принятый в типе, который преобразуется при использовании списков параметров, как float с поворотом в double с , я помещаю в исходный тип для T, или с искаженным типом? В случае, если это последнее, я делаю тип признаков для этого, для которого требуется продвинутый признак на последнем шаге.

+1

Я просто понял, что я мог вручную использовать 'decltype (declval () declval (): declval ())' вместо того, чтобы надеяться, что 'common_type' не переопределяется. (Вы можете переопределить 'common_type', если хотя бы один тип определен пользователем. Типы перечислений определяются пользователем и иногда могут быть затронуты рекламными акциями.) – CTMacUser

+0

« Предполагается, что условный оператор будет применять акции до дальнейшей оценки »- Нет, это не так. Это невозможно даже в C++, где результатом условного оператора может быть lvalue. – hvd

ответ

0

Грубо говоря, 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; 
} 

EDIT:

Для уточнения: это не представляется возможным использовать шаблоны для обнаружения что-то передается в C-стиле списка VARIADIC аргумента, как это определено, что В таких ситуациях компилятор выполняет определенные пользователем типы.

+0

В разделе 13.6 [over.built] продвижение произошло до этого момента. Например, если я использовал 'float', псевдо-декларация для' 'bool? T: T'' уже была бы' double'! Это то, что я хочу; Я хочу знать, может ли это потерпеть неудачу. Вероятно, он будет работать для целых типов, но подходит ли он для типов перечисления? – CTMacUser

+0

Теперь я немного смущен ... «bool? float: float' делает 'float'. Вы пытаетесь определить, к чему способствуется тип перечисления? Возможно, основной тип? Пример того, где это проблема, поможет вам. – defube

+0

Мне нужны черты типа для рекламных акций, перечисленных в разделах 4.5 [conv.prom] и 4.6 [conv.fpprom] Стандарта. Я хотел, чтобы они делали черты характера для манипуляции, перечисленные в разделе 5.2.2 [expr.call], параграф 7 (начиная с N3797). Конечно, для обеих трансформаций должны быть стандартные типы признаков, но мне это нужно скорее. – CTMacUser