2016-06-09 2 views
1

Если шаблон C++ содержит ошибку вопиющего типа, например ссылку на член класса, которая не существует, гарантирует ли стандарт языка обнаружение ошибки во время определения шаблона?Исправлены ли шаблоны C++ для синтаксических ошибок без их создания?

Или может быть обнаружена ошибка, обнаруженная только при создании экземпляра шаблона?

  1. Предположим, что ошибка не связана ни с одним из параметров шаблона?

  2. Предположим, что это связано с одним из параметров шаблона?

+2

Как бы вы проверили типы параметров, не указав их (т. Е. Создавая экземпляр шаблона)? Возможно, я не понял ваш вопрос, но есть, конечно, возможности проверить параметры шаблона для ограничений, но для этого вам нужны конкретные типы. Итак, ваш третий пункт описывает поведение в лучшем случае ИМО. –

+1

Непонятно, что вы просите. Что вы подразумеваете под * typechecking templates *? Подстановка параметра шаблона? – Drop

+0

@Drop OP, очевидно, означает проверку ограничений (так называемые понятия). –

ответ

0

Что касается вашего (оригинал) титул

Может ли шаблон C++ быть typechecked без инстанцировании это?

В зависимости от того, что конкретно обозначается typecheck.


делает язык стандартной гарантии для обнаружения ошибки в момент шаблон определяется?

Что касается объявления шаблона (!) И самого определения, он будет проверен на синтаксическую корректность перед созданием экземпляра, как вы упомянули в своем вопросе.

Существует несколько типа проверки сделано ...

template<typename T> 
class Foo { 
    Foo() : x(y) {} 
private: 
    int &x; 
    T z; 
}; 

int main() { 
} 

clang ============= 
main.cpp:4:20: error: use of undeclared identifier 'y' 
     Foo() : x(y) {} 
       ^
1 error generated. 
gcc ============= 
main.cpp: In constructor 'Foo<T>::Foo()': 
main.cpp:4:20: error: 'y' was not declared in this scope 
      Foo() : x(y) {} 
        ^

См Demo


... но не последовательно с

template<typename T> 
class Foo { 
    Foo() : x(Foo::y) {} 
private: 
    int &x; 
    T z; 
}; 

int main() { 
} 

clang ============= 
main.cpp:4:25: error: no member named 'y' in 'Foo<T>' 
     Foo() : x(Foo::y) {} 
        ~~~~~^ 
1 error generated. 
gcc ============= 

Demo


Где GCC также выдает ошибку, когда Foo фактически инстанцирован:

template<typename T> 
class Foo { 
public: 
    Foo() : x(Foo::y) {} 
private: 
    int &x; 
    T z; 
}; 

int main() { 
    Foo<int> foo; // <<<<<<<<<<<<<<<<<<<<< 
} 

clang ============= 
main.cpp:5:25: error: no member named 'y' in 'Foo<T>' 
     Foo() : x(Foo::y) {} 
        ~~~~~^ 
1 error generated. 
gcc ============= 
main.cpp: In instantiation of 'Foo<T>::Foo() [with T = int]': 
main.cpp:12:18: required from here 
main.cpp:5:26: error: 'y' is not a member of 'Foo<int>' 
      Foo() : x(Foo::y) {} 
         ^

Demo

Или гарантируется ошибка будет обнаружена только тогда, когда шаблон обрабатывается?

Так что это кажется правдой.


Насколько далеко идет речь, это конкретная деталь реализации компилятора.
Так что нет, очевидно, нет никаких стандартных гарантий относительно этого.

Кроме того, как @Jarod42 показал в их Clang/GCC sample

template <typename T> 
void foo() 
{ 
    int a = "hello world"; 
    const char* hello = 42; 
} 

int main() 
{ 
} 

clang ============= 
main.cpp:6:9: error: cannot initialize a variable of type 'int' with an lvalue of type 'const char [12]' 
    int a = "hello world"; 
     ^ ~~~~~~~~~~~~~ 
main.cpp:7:17: error: cannot initialize a variable of type 'const char *' with an rvalue of type 'int' 
    const char* hello = 42; 
       ^  ~~ 
2 errors generated. 
gcc ============= 

Так что я боюсь, что нет ничего более доступны, чем можно найти в разделе § 14.5 части c++ standard specification что такое считается допустимым синтаксисом объявления/определения шаблона.



Что касается прежних версий вашего вопроса:

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

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

Для этого шаблон должен быть установлен.


  • Возможно, шаблон много как макрос в Лиспе: компилятор проверяет синтаксис, но не проверка типов не будет сделано, пока шаблон не конкретизируется. И каждый раз, когда шаблон создается, компилятор снова запускает typechecker.

Это, кажется, ближе всего, хотя нет ничего, как проверки типов что работает во время компиляции, но в основном инстанцируют другие шаблонные классы и пусть std::static_assert решить, в конце концов, если ограничения для данного типа (или не-тип), удовлетворяются или нет.


Чтобы увидеть, как стандартная библиотека С ++ имеет дело с этим, см Library Concepts пожалуйста.


+0

Clang выполняет некоторую проверку типов без создания экземпляра (для типов, не зависящих от шаблонов): [Demo] (http://coliru.stacked-crooked.com/a/f0fa7b04afeddf2b). – Jarod42

+0

@ Jarod42 Я только что обновил свой ответ, написав этот комментарий. Конечно, декларация и определение шаблона проверяется (не только с clang IIRC). На самом деле вопрос действительно неясен. –

+1

У меня создалось впечатление, что «понятия» все еще являются экспериментальной функцией и еще не являются частью стандарта. Это изменилось? –

0

Проверка возможна, но не требуется. [temp.res]/8:

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

  • не действует специализация может быть сгенерирован для шаблона и шаблон не создается экземпляр, или

  • каждый действует специализация VARIADIC шаблона требует пустой параметр шаблона пакета, или

  • гипотетический экземпляра шаблона сразу после его определение будет плохо формируется за счет конструкции, которая не зависит от параметра шаблона, или

  • интерпретация такой конструкции в гипотетической инстанцировании отличается от интерпретации соответствующей конструкции в любой фактической экземпляре шаблона.

Обратите внимание, что две фазы поиск фактически не требует ранней проверки: различные поиски имен должны быть сделаны в контексте определения шаблона, но они на самом деле не требуется, чтобы быть сделаны в момент определение.

Смежные вопросы