如果永远不会被调用,那么类模板的成员函数是否会被实例化?

for*_*818 3 c++ templates

我刚开始了解一些模板基础知识.实际上,直到现在我才接受它为一个事实,但我真的不明白为什么这个被打破了:

template <typename T,bool hasFoo>
struct Broken {
    void foobar(){
        if (hasFoo){T::foo();}
        else { std::cout << "BROKEN" << std::endl;}
    }
};

int main(){
    Broken<int,false> t;
    t.foobar();
}
Run Code Online (Sandbox Code Playgroud)

虽然这有效:

template <typename T>
struct Works {
    void foo(){T::foo();}
    void bar(){std::cout << "WORKS" << std::endl;}
};

int main(){
    Works<int> t;
    t.bar();
}
Run Code Online (Sandbox Code Playgroud)

不知怎的,这是显而易见的,但我只是想确保我没有遗漏一些东西:这是否有效,因为如果函数Works<int>::foo()永远不会被调用,它就不会被实例化?

PS:为了避免误解:我知道,为什么会Broken被打破,我最近有一个与此相关的问题,我得到了很好的答案,但之后我认为也不Works<int>应该编译,直到我不小心通过"错误的"模板参数并且感到惊讶它确实编译了.

son*_*yao 7

如果从未调用函数Works :: foo(),它只是没有实例化?

是的,类模板的非虚拟成员函数在需要之前不会被实例化.

从标准,§12.8.1/ 10隐式实例化[temp.inst]:

(强调我的)

实现不应隐式实例化函数模板,变量模板,成员模板,非虚拟成员函数,成员类,类模板的静态数据成员或constexpr if语句的子语句([stmt.如果]),除非需要这样的实例化.