«if constexpr(что-то ложное)» ВСЕГДА пропускает создание экземпляра шаблона

Будет ли эта функция шаблона 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.

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

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
0
221
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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 28.05.2019 07:18

@cppBeginner — начинается с тимсонг-cpp.github.io/cppwp/n4659/temp.spec#1

StoryTeller - Unslander Monica 28.05.2019 07:19

Всегда ли «создание экземпляра» в С++ относится к «созданию экземпляра шаблона»?

cppBeginner 28.05.2019 07:24

@cppBeginner - я никогда не сталкивался с его использованием в других контекстах.

StoryTeller - Unslander Monica 28.05.2019 07:25

Другие вопросы по теме