2013-12-23 2 views
9

Я, кажется, вспоминаю смутные комментарии нескольких достоверных источников (т. Е. Членов комитета, выступающих в неофициальных каналах), что выражающие C-типы выражения не будут добавлены в C++, потому что их не может быть.Почему C-образные выражения типа C не совместимы с C++?

Насколько я могу судить, типовые выражения очень ограничены по сравнению с шаблонами C++ и перегрузкой, но нет никакого потенциала для взаимодействия, которое необходимо было бы определить как частный случай.

Типичное выражение состоит из управляющего выражения и ряда «ассоциаций» между типами и подвыражениями. Подвыражение выбирается на основе статического типа управляющего выражения и типов, перечисленных для подвыражений, и вместо ТЭГ заменяется. Согласование основано на концепции совместимости типов C, которая, насколько я могу судить, эквивалентна идентичности типов C++ типов с привязкой extern в соответствии с правилом определения (ODR).

Было бы неплохо, если бы выражение, определяющее производный класс, выбрало бы ассоциацию базового класса в C++, но поскольку C не имеет наследования, такая тонкость не нужна для кросс-совместимости. В любом случае, считается ли это камнем преткновения?

Edit: Что касается более конкретных деталей, C11 уже предусматривает сохранение категории стоимости (именующий-Ness) выбранное подвыражения, и, кажется, требует, чтобы TGE является постоянным выражением (в каком бы категории) до тех пор, как и все его операнды, включая контрольное выражение. Вероятно, это дефект языка C. В любом случае, C++ 14 определяет постоянные выражения с точки зрения потенциальной оценки, а спецификация TGE уже говорит о том, что невыбранные подвыражения не оцениваются.

Дело в том, что принцип работы TGE кажется достаточно простым, чтобы его можно было пересаживать, даже не вызывая проблемы позже.

Что касается почему C++ TGE был бы полезно, помимо максимизации пересечения C и C++, они могут быть использованы для реализации по существу static_if, SANS весьма спорной условной функции декларации. Я не сторонник 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'; 
} 
+0

Возможно, дело в том, что решение об общем рождении должно прийти перед тем, что определяет, как работают классы. Таким образом, вы не сможете генерировать классы, и, следовательно, у вас будет функция, которая работает только с некоторыми типами. – leewz

+1

@leewangzhong Ну, это будет работать так же, как в C.Он будет работать на всех типах, просто не с пониманием наследования. – Potatoswatter

+0

Я имею в виду, возможно, типы C++ не распознаются к моменту, когда генерические средства будут разрешены. – leewz

ответ

1

«Не может быть», возможно, слишком сильным. «Непонятно, возможно ли это».

Если эта функция должна быть добавлена ​​в C++, она должна быть полностью указана, включая все взаимодействия с существующими функциями C++, многие из которых не были разработаны с учетом _Generic. Например. typeid не существует в C, но должен работать на C++. Можете ли вы использовать выражение _Generic как constexpr? Как параметр шаблона? Это lvalue? Можете ли вы взять его адрес и назначить его указателю на функцию и получить разрешение перегрузки? Можете ли вы сделать вывод аргумента шаблона? Можете ли вы использовать его с auto? И т. Д.

Еще одно осложнение состоит в том, что основная функция для _Generic предназначена для макросов, которые не играют хорошо с пространствами имен C++. Ярким примером является пример acos от tgmath. C++ уже запретил стандартные макросы C и потребовал, чтобы они были функциями, но это не сработает с tgmath.h.

+2

Эти звуки больше похожи на отметки, которые необходимо проверить без взаимодействия. Идея заключается в том, что одно подвыражение выбрано и заменено всем выражением. Как таковой, кажется, нет места для взаимодействия с любой из вещей, о которых вы упомянули. Что касается макросов 'tgmath', они уже перегружены наборами перегрузки с C++ 98. – Potatoswatter