Что касается вашего (оригинал) титул
Может ли шаблон 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 пожалуйста.
Как бы вы проверили типы параметров, не указав их (т. Е. Создавая экземпляр шаблона)? Возможно, я не понял ваш вопрос, но есть, конечно, возможности проверить параметры шаблона для ограничений, но для этого вам нужны конкретные типы. Итак, ваш третий пункт описывает поведение в лучшем случае ИМО. –
Непонятно, что вы просите. Что вы подразумеваете под * typechecking templates *? Подстановка параметра шаблона? – Drop
@Drop OP, очевидно, означает проверку ограничений (так называемые понятия). –