Подтвердить что ты не робот

Какова цель std:: common_type?

Я начал смотреть std::common_type и не совсем уверен в своей цели и ее функциональности. Несколько вещей по-прежнему кажутся мне странными:

  • Порядок аргументов важен: common_type<Foo, Bar, Baz> может отличаться от common_type<Baz, Foo, Bar>. Или может компилироваться, а другой - нет. Хотя это ясно из определения common_type, оно кажется странным и неинтуитивным. Это из-за отсутствия универсального решения или намерения?
  • Активация может привести к ошибке компилятора вместо того, что я могу обработать. Как проверить, действительно ли будет common_type компилировать? is_convertible недостаточно, поскольку common_type может быть специализированным?
  • До сих пор нет способа определить общий тип в такой ситуации:

    struct Baz;
    struct Bar { int m; };
    struct Foo { int m; }; 
    struct Baz { Baz(const Bar&); Baz(const Foo&); };
    

    Рекомендуемое решение - специализировать common_type, который является утомительным. Есть ли лучшее решение?

Для справки см. §20.9.7.6 Таблица 57 в N3242.

4b9b3361

Ответ 1

std::common_type был введен для использования с std::duration --- если вы добавите std::duration<int> и a std::duration<short>, тогда результат должен быть std::duration<int>. Вместо того, чтобы указывать бесконечный поток разрешенных пар, было принято решение делегировать отдельный шаблон, который нашел результат, используя правила основного языка, применимые к оператору арифметики ?:.

Затем люди увидели, что этот шаблон обычно полезен, и он был добавлен как std::common_type и расширен для обработки произвольного количества типов. В библиотеке С++ 0x он используется только для пар типов.

Вы должны иметь возможность использовать новые правила SFINAE для определения того, действительна ли какая-либо инстанция std::common_type. Я еще не пробовал. В большинстве случаев, если нет "общего типа", то нет ничего значимого, что вы можете сделать в любом случае, поэтому ошибка компиляции является разумной.

std::common_type не является магическим - он следует правилам ?:. Если true?a:b будет компилироваться, std::common_type<decltype(a),decltype(b)>::type даст вам тип результата.