C ++ 0x, перехваты компилятора и функции жестко закодированных языков

StackOverflow https://stackoverflow.com/questions/1857484

Вопрос

Мне немного любопытно узнать о некоторых новых функциях C ++ 0x.В частности циклы, основанные на диапазоне и списки инициализаторов.Для корректного функционирования обеих функций требуется определенный пользователем класс.

Я наткнулся на этот пост, и хотя главный ответ был полезным.Я не знаю, полностью ли это правильно (Вероятно, я просто совершенно неправильно понимаю, см. 3-й комментарий к первому ответу).В соответствии с текущие технические характеристики для списков инициализаторов заголовок определяет один тип:

template<class E> class initializer_list {
public:
    initializer_list();

    size_t size() const; // number of elements
    const E* begin() const; // first element
    const E* end() const; // one past the last element
};

Вы можете увидеть это в спецификациях, просто нажав Ctrl + F 'список инициализаторов класса'.

Для того, чтобы = {1,2,3} быть неявно приведенным в initializer_list класса, компилятор ДОЛЖЕН обладать некоторыми знаниями о взаимосвязи между {} и initializer_list.Нет конструктора, который что-либо получает, поэтому initializer_list, насколько я могу судить, является оболочкой, которая привязывается к тому, что на самом деле генерирует компилятор.

То же самое и с for( : ) цикл, для работы которого также требуется пользовательский тип (хотя, согласно спецификациям, обновлен, чтобы не требовать никакого кода для массивов и списков инициализаторов.Но списки инициализаторов требуют <initializer_list>, так что это пользовательское требование к коду через прокси).

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

Редактировать: Я набрал "сильно полагаться на код компилятора", а не "сильно полагаться на код пользователя".Что, я думаю, полностью опровергло мой вопрос.Мое замешательство связано не с новыми функциями, встроенными в компилятор, а с вещами, которые встроены в компилятор и зависят от пользовательского кода.

Это было полезно?

Решение

Я не ошибаюсь, думая, что эти новые функции фактически чрезвычайно сильно зависят от кода компилятора

Они в значительной степени полагаются на компилятор.Независимо от того, нужно ли вам включать заголовок или нет, факт заключается в том, что в обоих случаях синтаксис был бы ошибкой синтаксического анализа с современными компиляторами.Тот самый for (:) не совсем вписывается в современный стандарт, где единственной разрешенной конструкцией является for(;;)

Такое ощущение, что функции подготовлены наполовину, и вместо того, чтобы встраивать всю функцию в компилятор, она наполовину выполняется компилятором, а наполовину - includes .В чем причина этого?

Поддержка должна быть реализована в компиляторе, но для ее работы вам необходимо включить системный заголовок.Это может служить нескольким целям, в случае списков инициализации, это вводит тип (интерфейс для поддержки компилятора) в область видимости для пользователя, чтобы у вас был способ его использования (подумайте, как va_args в C).В случае for, основанного на диапазоне (который является просто синтаксическим сахаром), вам нужно ввести Range в область видимости, чтобы компилятор мог выполнить это волшебство.Обратите внимание, что стандарт определяет for ( for-range-declaration : expression ) statement как эквивалент ([6.5.4]/1 в проекте):

{ 
   auto && __range = ( expression ); 
   for ( auto __begin = std::Range<_RangeT>::begin(__range), 
         __end = std::Range<_RangeT>::end(__range); 
         __begin != __end; 
         ++__begin ) { 
      for-range-declaration = *__begin; 
      statement 
   } 
} 

Если вы хотите использовать его только для массивов и контейнеров STL, которые могли бы быть реализованы без Range концепция (не в смысле C ++ 0x), но если вы хотите расширить синтаксис до пользовательских классов (ваших собственных контейнеров), компилятор может легко зависеть от существующего Range шаблон (с вашей собственной возможной специализацией).Механизм зависимости от определяемого шаблона эквивалентен требованию статического интерфейса в контейнере.

Большинство других языков пошли в направлении требования обычного интерфейса (скажем, контейнера, ...) и использования для этого полиморфизма во время выполнения.Если бы это было сделано на C ++, весь STL должен был бы пройти серьезный рефакторинг, поскольку контейнеры STL не имеют общей базы или интерфейса, и они не готовы к полиморфному использованию.

Если таковой имеется, текущий стандарт не будет соответствовать недообжаренный к тому времени, как он погаснет.

Другие советы

Это просто синтаксический сахар.Компилятор расширит данные синтаксические конструкции в эквивалентные выражения C++, которые напрямую ссылаются на стандартные типы/имена символов.

Это не единственная сильная связь, которую современные компиляторы C++ имеют между своим языком и «внешним миром».Например, extern "C" это своего рода языковой хак, позволяющий реализовать модель связывания C.Языко-ориентированные способы объявления локального хранилища потока неявно зависят от множества хакерских приемов RTL.

Или посмотрите на книгу С.Как получить доступ к аргументам, передаваемым через ...?Вам нужно полагаться на стандартную библиотеку;но здесь используется магия, которая очень сильно зависит от того, как именно компилятор C размещает кадры стека.

ОБНОВЛЯТЬ:

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top