"if constexpr(something false)" 是否总是忽略模板实例化

Does "if constexpr(something false)" ALWAYS omit template instantiation

此模板函数 f<X>() 是否始终不实例化?

if constexpr(something false){
     //some template function OR function in template class
     f<X>();
}

下面是我的测试(coliru MCVE)。
我创建了 fun<S>() 当且仅当 S!=void.
时才会实例化 E<S> 然后我调用 fun<void>()fun<int>()fun<float>().

我相信 if constexpr(false) 强制 C++ 编译器跳过 fun<void>()#1 部分。
我的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 and "If constexpr" in C++17 does not work in a non-templated function

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.

规则中的 "instantiated" 这个词我还是不太确定。它与"template instantiation"中的含义相同吗?

Does it have the same meaning as in "template instantiation"?

是的,确实如此。该规范谈到 "discarded" 语句,并且仅在某些封闭模板化实体的模板实例化上下文中有意义。

[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.

重要的一点是参数被替换后的条件是value-dependent。一方面,这意味着如果条件仅取决于正在实例化的直接封闭模板的参数,则它不会成为该模板实例化的一部分。

在你的例子中,这意味着如果 std::is_same_v<void,S> 为真,"if" 的主体将不会成为实例化 fun<void> 的一部分。