C : принудительная полная компиляция шаблонов (MSVC / G )

#c #visual-studio-2008 #templates #visual-c #g

#c #visual-studio-2008 #шаблоны #visual-c #g

Вопрос:

Здравствуйте и доброго вам дня.

Следующий фрагмент кода компилируется на cl.exe (15.00.30729.01) и mingw-g (4.4.0):

 template<typename T> class Test{
public:
    T t;
    void error(){
        int doesNotExist = 6;
        return doesNotExist;//<---- void function returning result
    }
};

int main(int argc, char** argv){
    Test<int> test;
    return 0;
}
 

Кроме того, на cl.exe вам даже может сойти с рук что-то подобное:

 template<typename T> class Test{
public:
    T t;
    void error(){
        doesNotExist = 6;//<---- undeclared variable
        return doesNotExist;//<---- void function returning result
    }
};
 

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

Вопрос:
Есть ли переключатель компилятора для g или cl.exe это заставило бы компилятор обрабатывать весь шаблон целиком (так что этот фрагмент кода вызовет ошибку компиляции)?

Ответ №1:

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

 // at namespace level
template class Test<int>;
 

Явные экземпляры шаблонов классов автоматически запускают создание экземпляров всех членов, что, похоже, то, что вы хотите.

Реальная проблема заключается в том, что язык разработан так, чтобы явно разрешать поведение, которого вы хотите избежать. Когда шаблон класса создается неявно, компилятор создает экземпляры только тех методов, которые используются. Основной вариант использования этой функции заключается в том, что некоторые методы могут предъявлять более строгие требования к типу создания экземпляра, чем другие, если бы все методы создавались всегда, тогда шаблон класса можно было бы использовать только с теми типами, которые отвечают более строгим требованиям.

Позволяя компилятору создавать экземпляры только тех методов, которые используются, шаблон класса можно использовать с типами, которые не отвечают всем требованиям всех методов, если они соответствуют требованиям фактически используемых методов.

Распространенный пример заключается operator[] в std::map<> том, что требуется value_type , чтобы объект был сконструирован по умолчанию ( operator[] создаст новый объект, инициализированный по умолчанию, если ключ отсутствует в контейнере, и вернет ссылку на него). Поведение языка позволяет использовать std::map типы, которые не могут быть сконструированы по умолчанию, пока вы не используете operator[] (или любую другую функцию-член, которая предъявляет это требование).

Комментарии:

1. Да, явное создание экземпляра шаблона — это то, что вам нужно. Также смотрите: msdn.microsoft.com/en-us/library/by56e477(VS.80).aspx

2. Хорошее объяснение фактической цели отсутствия ошибки компилятора.

3. Хорошо, это работает. Я принимаю ваш ответ, но на самом деле не было необходимости объяснять, ПОЧЕМУ это работает таким образом (я уже знал). Спасибо за ответ.