Кажется, я помню, что слышал расплывчатые комментарии из нескольких надежных источников (то есть членов комитета, говорящих по неофициальным каналам), что выражения общего типа C не будут добавлены в C ++, потому что они не могут быть.
Насколько я могу судить, типовые выражения очень ограничены по сравнению с шаблонами C ++ и их перегрузкой, но нет никакого потенциала для взаимодействия, которое нужно было бы определить как особый случай.
Типовое выражение состоит из управляющего выражения и серии «ассоциаций» между типами и подвыражениями. Подвыражение выбирается на основе статического типа управляющего выражения и типов, перечисленных для подвыражений, и заменяется вместо TGE. Сопоставление основано на концепции совместимости типов C, которая, насколько я могу судить, эквивалентна идентичности C ++ типов с extern
связь по правилу единого определения (ODR).
Было бы неплохо, если бы управляющее выражение производного класса выбрало бы ассоциацию базового класса в C ++, но, поскольку C не имеет наследования, такая мелочь не требуется для перекрестной совместимости. В любом случае считается ли это камнем преткновения?
Редактировать: Что касается более конкретных деталей, C11 уже обеспечивает сохранение категории значений (lvalue-ness) выбранного подвыражения и, по-видимому, требует, чтобы TGE был постоянным выражением (любой категории), пока все его операнды, включая контролирующее выражение. Это, вероятно, дефект языка Си. В любом случае, C ++ 14 определяет константные выражения в терминах того, что может быть потенциально оценено, а спецификация TGE уже говорит, что невыбранные подвыражения не оценены.
Дело в том, что принцип работы TGE кажется достаточно простым, чтобы его можно было пересаживать, не вызывая проблем позже.
Что касается Зачем Были бы полезны C ++ TGE, помимо максимального пересечения C и C ++, их можно было бы использовать для реализации static_if
, Без весьма спорная условного заявления особенности. Я не сторонник static_if
, но «есть что».
template< typename t >
void f( t q ) {
auto is_big = _Generic( std::integral_constant< bool, sizeof q >= 4 >(),
std::true_type: std::string( "whatta whopper" ),
std::false_type: "no big deal");
auto message = _Generic( t, double: "double", int: 42, default: t );
std::cout << message << " " << is_big << '\n';
}
«Не может быть», возможно, слишком сильно. «Не уверен, возможно ли это» более вероятно.
Если эта функция должна быть добавлена в C ++, она должна быть полностью указана, включая все взаимодействия с существующими функциями C ++, многие из которых не были разработаны с _Generic
в уме. Например. typeid
не существует в C, но должен работать в C ++. Можете ли вы использовать _Generic
выражение как constexpr
? Как параметр шаблона? Это lvalue
? Можете ли вы взять его адрес и присвоить его указателю на функцию, и получить разрешение перегрузки? Можете ли вы сделать вывод аргумента шаблона? Можете ли вы использовать его с auto
? И т.п.
Другое осложнение заключается в том, что основной сценарий использования _Generic
предназначен для макросов, которые плохо работают с пространствами имен C ++. acos
пример из tgmath
это яркий пример. C ++ уже запретил стандартные макросы C и требовал, чтобы они были функциями, но это не сработает tgmath.h
,
Других решений пока нет …