Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
Разработка программного обеспечения

THE BOOST MPL LIBRARY: ETI

Boost , ,

Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

Front Page / Technical Details / Portability / ETI

ETI

В контексте проблем с шаблонами C++ ETI является аббревиатурой для "Early Template Instantiation" — Microsoft Visual C++ — конкретной проблемы, которая была препятствием для любой серьезной работы с шаблонами на этой платформе, пока разработчики Microsoft не исправили ее в Visual C++ 7.1 (2003 .NET). Хотя проблема относительно проста, если правильные методы систематически применяются через кодовую базу, подход, безусловно, утомительный и трудоемкий. Поэтому, если однажды вы обнаружите, что тратите слишком много времени на решение этой проблемы, рассмотрите возможность обновления до новой версии компилятора. На самом деле, серьезно отнеситесь к этому независимо. Преимущества сэкономленного времени, денег и разочарования стоят своей цены.

The Problem

Вот краткая демонстрация проблемы с MSVC 6.x:

template< typename F, typename T > struct apply1
{
    typedef typename F::template apply<T>::type type;
};

Пытаясь составить этот невинно выглядящий код, мы получаем:

portability.cpp(4) : error C2903: 'apply' : symbol is neither a class template 
            nor a function template
        portability.cpp(5) : see reference to class template instantiation 
            'apply1<F,T>' being compiled
portability.cpp(4) : error C2143: syntax error : missing ',' before '<'
        portability.cpp(5) : see reference to class template instantiation 
            'apply1<F,T>' being compiled
portability.cpp(4) : error C2059: syntax error : '<'
        portability.cpp(5) : see reference to class template instantiation 
            'apply1<F,T>' being compiled

Символ не является ни шаблоном класса, ни шаблоном функции; часть диагностики на самом деле часто указывает на проблемы, связанные с ИППП. Другое типичное сообщение об ошибке обычно говорит о том, что вложенный тип не является членом глобального пространства имен.

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

ETI всегда выполняется во время разбора определения шаблона пространства имен, что в основном означает, что любое определение шаблона, которое становится недействительным, заменяя его параметры шаблона ints, может не компилироваться, как это произошло с нашим примером:

template< typename F, typename T > struct apply1
{
    // typedef typename F::template apply<T>::type type;
    // ETI generates this: 
    typedef typename int::template apply<int>::type type;
};

Если вы сделаете это, вы получите точно Диагностика, которую мы только что видели.

Обратите внимание, что мы сказали "может не компилировать", потому что ... ну, короткий ответ: "это зависит". Мы не анализировали вещи до такой степени, что мы могли бы сказать вам точное состояние, когда ETI приводит к ошибке, а когда нет, но это не очень важно в любом случае - если это ошибка, вы просто исправите ее (мы покажем вам, как через секунду), и если это не так, то вы оставляете вещи такими, какие они есть. Если однажды потенциальная проблема превратится в реальную, вы применяете обходной путь, который мы собираемся вам дать.

The Symptoms

Мы уже рассмотрели типичную диагностику, поэтому не будем повторяться. Вместо этого мы просто упомянем, что многие внутренние ошибки MSVC на самом деле вызваны проблемой, связанной с ETI, где-то в глубине стека инстанциации.

The Solution

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

// potentially unsafe
template< typename F > struct apply0
{
    typedef typename F::type type;
};
// now ETI-safe
template<> struct apply0<int>
{
    typedef int type;
};

Поскольку исходный шаблон никогда не мог быть инстанцирован с int, предоставление специализации stub int совершенно невинно.

Статья THE BOOST MPL LIBRARY: ETI раздела может быть полезна для разработчиков на c++ и boost.




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.



:: Главная :: ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-08-30 11:47:00
2025-05-20 02:28:47/0.0063850879669189/1