ошибки шаблона - PullRequest
       2

ошибки шаблона

3 голосов
/ 19 августа 2010

Я слышал, что шаблоны C ++ не будут генерировать ошибки, пока они не будут использованы. Это правда ? Может кто-нибудь объяснить мне, как они работают?

Ответы [ 4 ]

6 голосов
/ 19 августа 2010

Шаблоны следуют двухфазной модели компиляции.

struct X{
private:
   void f(){}
};

template<class T> void f(T t){
   int;   // gives error in phase 1 (even if f(x) call is commented in main)
   t.f(); // gives error only when instantiated with T = X, as x.f() is private, in phase 2
}

int main(){
   X x;
   f(x);
}
1 голос
/ 19 августа 2010

Они генерируют ошибки компилятора при компиляции. Они компилируются отдельно для каждого фактического параметра, передаваемого в качестве аргумента (ов) шаблона (это не похоже на Generics Java), например, , если я имею:

template <typename T> class foo { ... }

и

int main() {
  foo<char> c;
  foo<int> i ;
}

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

Если вы никогда (прямо или косвенно) не создавали и не использовали шаблон foo, он не будет скомпилирован и вы не увидите ошибок компилятора.

После компиляции они являются просто «нормальным» кодом C ++ и, как и любой другой код, могут генерировать ошибки времени выполнения.

0 голосов
/ 19 августа 2010

Концептуально, на самом высоком уровне

template <Type value, class Y, ...>
...fn-or-class...

можно с пользой сравнить с

#define FN_OR_CLASS(VALUE, TYPE_Y, ...) \
...fn-or-class...

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

Когда компилятор впервые встречает шаблон, он выполняет грубую проверку того, что содержимое шаблона может иметь смысл для некоторой гипотетической реализации.Позже, когда он встречает конкретную реализацию, тогда для шаблонов классов дополнительно проверяются только те функции, которые используются , чтобы убедиться, что они могут быть скомпилированы с конкретными параметрами, которые используются.Это означает, что шаблон класса может появиться - для некоторого ограниченного использования - для поддержки создания экземпляров с определенными параметрами, но если вы начнете использовать некоторые другие функции в API-интерфейсе шаблона, то внезапно вы обнаружите, что он не может быть скомпилирован с этим предполагаемымподходящий параметр ... может заставить вас изменить дизайн использования довольно поздно в день.Это одна из причин, по которой C ++ 0x планировал ввести Концепции: они элегантно позволяют шаблонам проверять, соответствуют ли параметры всем ожиданиям шаблона - если они допускают какую-либо реализацию, то пользователь может предположить, что полный API шаблона может

template <class T>
struct X
{
    void f() { }
    void g() { T::whatever(); } // only error if g() called w/o T::whatever
};

int main()
{
    X<int> x;
    x.f();
    // x.g(); // would cause an error as int::whatever() doesn't exist...
}

Метод SFINAE (ошибка замещения не является ошибкой) может затем позволить компилятору выбирать между несколькими почти совпадающими функциями на основе фактических параметров экземпляра шаблона.Это может быть использовано для реализации базового самоанализа во время компиляции, такого как «имеет ли этот класс функцию-член fn (int)?».

0 голосов
/ 19 августа 2010

С здесь ,

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

Надеюсь, это поможет ..

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...