我刚刚开始了解一些模板基础知识。实际上,直到现在我才接受它作为事实,但我不太明白为什么会这样:
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();
}
虽然这有效:
template <typename T>
struct Works {
void foo(){T::foo();}
void bar(){std::cout << "WORKS" << std::endl;}
};
int main(){
Works<int> t;
t.bar();
}
不知怎的,这是显而易见的,但我只是想确保我没有遗漏一些东西:
这行得通吗,因为如果函数Works<int>::foo()
从未被调用,它根本没有被实例化?
PS:为了避免误会:我知道,为什么Broken
坏了,我最近有一个question https://stackoverflow.com/questions/33465830/how-to-fix-this-template与此相关,我得到了很好的答案,但在那之后我也认为Works<int>
不应该编译,直到我不小心传递了一个“错误”的模板参数,并对它确实编译感到惊讶。
如果函数 Works::foo() 从未被调用,它根本就没有被实例化?
是的,类模板的非虚拟成员函数在需要时不会被实例化。
从标准来看,§12.8.1/10 隐式实例化 [temp.inst] http://eel.is/c++draft/temp.inst#10:
(强调我的)
实现不应隐式实例化函数
模板、变量模板、成员模板、一个非虚拟的
成员函数、成员类、类的静态数据成员
模板,或 constexpr if 语句 ([stmt.if]) 的子语句,
除非需要这样的实例化。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)