这个模板函数f<X>()
是否总是不被实例化?
if constexpr(something false){
//some template function OR function in template class
f<X>();
}
下面是我的测试(coliru MCVE)。
我创建fun<S>()
了它将实例化E<S>
当且仅当S!=void
.
然后我打电话给fun<void>()
,fun<int>()
和fun<float>()
。
我相信强制 C++ 编译器if constexpr(false)
跳过#1
.
我的应该只有2次。 fun<void>()
countRunner
++
因此,如果我的假设是正确的,那么下面的程序将始终在每个编译器和每个设置中打印 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和C++17 中的“If constexpr”在非模板函数中不起作用。
如果if语句的形式为if constexpr,则条件的值应为 bool 类型的上下文转换的常量表达式;这种形式称为constexpr if语句。如果转换条件的值为假,则第一个子语句是丢弃的语句,否则第二个子语句(如果存在)是丢弃的语句。在封闭模板化实体的实例化过程中,如果条件在其实例化后不依赖于值,则丢弃的子语句(如果有)不会被 实例化。[ 注意:废弃语句中的 Odr 使用不需要定义实体。— 尾注]案例或默认值出现在这种if语句中的标签应与同一if语句中的 switch 语句相关联。在 constexpr if 语句的子语句中声明的标签只能由同一子语句中的语句引用。
我仍然不确定规则中的“实例化”一词。它与“模板实例化”中的含义相同吗?