如果从不调用,类模板的成员函数是否不会被实例化
Does the member function of class template not get instantiated if never be called?
我刚刚开始了解一些模板基础知识。事实上,到目前为止,我只是接受了这一事实,但我真的不明白这被打破的原因:
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
为什么坏了,我最近有一个与此相关的问题,我得到了很好的答案,但在那之后,我认为Works<int>
也不应该编译,直到我意外地传递了一个"错误"的模板参数,并对它确实编译感到惊讶。
如果函数Works::foo()从未被调用,那么它就不会被实例化?
是的,类模板的非虚拟成员函数在需要之前不会被实例化。
根据标准,§12.8.11/10隐式实例化[temp.inst]:
(重点矿井)
实现不应隐式实例化函数模板,变量模板,成员模板,非虚拟成员函数,成员类,类的静态数据成员模板或constexpr-if语句的子语句([stmt.if]),除非需要这样的实例化。
要回答标题中的问题,不,不需要调用它来实例化。
此代码不进行编译,但从未调用foo
。
template <typename T>
struct Works {
void foo(){T::foo();}
void bar(){}
};
// this requires foo being instantiated because it may be called from
// elsewhere - the compiler cannot know.
template Works<int>;
int main(){
Works<int> t;
t.bar();
}
现场:https://godbolt.org/g/u4frVZ
这就是为什么标准说,除非需要实例化,否则它不会被实例化,而这方面的规则比是否调用它更复杂。
相关文章:
- 如何使用指针传递给函数的数组中对象的函数成员
- c++构造函数成员初始化:传递参数
- 创建 std::函数,它返回具有函数成员值的变量.分段错误
- 如何在C++通过公共函数访问私有函数成员?
- 解释了构造函数成员初始化列表
- 调用std::函数成员时内存损坏
- 是否可以为模板类的模板函数成员设置别名?
- 捕获 lambda 函数C++成员变量
- 构造函数成员初始值设定项跨成员列出,安全吗?
- 获取与在模板参数中传递的函数成员类型相同的类
- 如何从公共函数成员访问地图私有成员
- C 构造函数成员分配优化
- 使用命名空间进行函数成员定义
- 函数成员作为 CUDA 内核的参数
- 模板基类函数成员的别名
- 函数成员中用于void和继承的enable_if
- 头文件中是否定义了一个很长的Class函数成员
- 类内/构造函数成员初始化
- 使用指向部分专用函数成员的指针自动填充向量
- 指向函数成员的指针