Будет ли эта функция шаблона f<X>()
всегда НЕ создаваться?
if constexpr(something false){
//some template function OR function in template class
f<X>();
}
Ниже мой тест (колиру MCVE).
Я создал fun<S>()
, который будет создавать экземпляр E<S>
тогда и только тогда, когда S!=void
.
Затем я звоню fun<void>()
,fun<int>()
и fun<float>()
.
Я считаю, что if constexpr(false)
заставляет компилятор C++ пропустить часть #1
для fun<void>()
.
Мой countRunner
должен быть ++
всего 2 раза.
Таким образом, если мое предположение верно, приведенная ниже программа будет всегда печатать 2 в каждом компиляторе и каждой настройке.
(У меня было напечатано 2, но сам по себе эксперимент ничего не доказывает.)
#include<iostream>
int countRunner=0;
template<class T> class E{
public: static int countIndex;
public: E(){
if (false){
int unused=E::countIndex;
}
}
};
template<class T> int E<T>::countIndex=countRunner++;
template<class S> void fun(){
if constexpr(!std::is_same_v<void,S>){
E<S> e; //#1 - S=int,float, but never void
}
}
int main (){
fun<void>();
fun<int>();
std::cout<<"testResult = "<<countRunner<<std::endl;
fun<float>();
}
Могу ли я рассчитывать, что E<void>
никогда не будет создан экземпляр?
Пожалуйста, предоставьте какую-нибудь (полу-)официальную ссылку, чтобы я успокоился.
Редактировать: Я только что нашел http://eel.is/c++draft/stmt.if#2 и «Если constexpr» в С++ 17 не работает в нешаблонной функции.
If the if statement is of the form if constexpr, the value of the condition shall be a contextually converted constant expression of type bool; this form is called a constexpr if statement. If the value of the converted condition is false, the first substatement is a discarded statement, otherwise the second substatement, if present, is a discarded statement. During the instantiation of an enclosing templated entity, if the condition is not value-dependent after its instantiation, the discarded substatement (if any) is not instantiated. [ Note: Odr-uses in a discarded statement do not require an entity to be defined. — end note ] A case or default label appearing within such an if statement shall be associated with a switch statement within the same if statement. A label declared in a substatement of a constexpr if statement shall only be referred to by a statement in the same substatement.
Я до сих пор не уверен в слове «создано» в правиле. Имеет ли это то же значение, что и в «создание экземпляра шаблона»?
Does it have the same meaning as in "template instantiation"?
Да, это так. Спецификация говорит об «отброшенных» операторах и имеет смысл только в контексте создания экземпляра шаблона для некоторого включающего шаблонного объекта.
[stmt.if] (emphasis mine)
2 If the if statement is of the form if constexpr, the value of the condition shall be a contextually converted constant expression of type bool; this form is called a constexpr if statement. If the value of the converted condition is false, the first substatement is a discarded statement, otherwise the second substatement, if present, is a discarded statement. During the instantation of an enclosing templated entity, if the condition is not value-dependent after its instantiation, the discarded substatement (if any) is not instantiated.
Важным битом является то, что условие зависит от значения после замены параметров. С одной стороны, это означает, что если условие зависит только от параметров непосредственно включающего шаблона, который создается экземпляром, оно не будет частью создания экземпляра этого шаблона.
В вашем случае это означает именно то, что если std::is_same_v<void,S>
верно, тело «если» не будет частью созданного экземпляра fun<void>
.
@cppBeginner — начинается с тимсонг-cpp.github.io/cppwp/n4659/temp.spec#1
Всегда ли «создание экземпляра» в С++ относится к «созданию экземпляра шаблона»?
@cppBeginner - я никогда не сталкивался с его использованием в других контекстах.
Благодарить. Могу ли я узнать больше об «экземпляре»? Где слово определено в стандарте С++?