因为在C ++中,当您使用模板时,在实例化之前不会生成代码。编译器只会为实例化类型生成代码。这是否意味着当我的代码(使用模板)编译时,我可以确定没有类型冲突,并且我的代码在运行时不会因类型错误而崩溃?
如果没有,有人可以提供一个示例,其中模板代码成功编译但仍然在运行时崩溃?
答案 0 :(得分:2)
不完全是您的问题,但严格相关的是,您可以让某些类型的模板实例化成功,而其他类型则失败。
例如:
template <class T>
struct xyz_t
{
std::string string_value(void) const{ return v; }
T v;
};
void abc(void)
{
xyz_t<std::string> a;
xyz_t<int> b;
a.string_value(); // compiles
b.string_value(); // fails, because returns int for std::string
}
这是概念试图解决的问题:找出对模板参数施加的约束,以确保成功编译。
答案 1 :(得分:2)
由于模板实例化导致生成的代码依赖于模板参数,因此所需的一切都是模板实例化之一导致产生“崩溃”的代码。
然后归结为“崩溃”的意思。如果“崩溃”包括抛出异常而没有被程序捕获(因此调用terminate()
),以下将编译但会产生崩溃
#include <stdexcept>
#include <vector>
struct foo
{
foo() {throw std::runtime_error("crash");};
};
int main()
{
std::vector<double> d(2); // okay, unless memory allocation fails
std::vector<foo> f(2); // will throw an exception
}
如果您的意思是代码可以表现出未定义的行为(这意味着可能发生任何事情,但是一个可能的结果是异常的程序终止),那么在上面更改foo
的构造函数以展示未定义的行为。例如,取消引用NULL指针,除以等等。不保证“崩溃”(这是未定义行为的性质),但在这种情况下是一种明显的可能性。
答案 2 :(得分:1)
编译器在编译时强制执行所有C ++类型规则。显然,只有在知道所有类型之后才会发生这种情况,这意味着所有模板都会被实例化。
您可能仍然会dynamic_cast
检查返回nullptr
或在运行时抛出,但这是设计的:dynamic_cast
是一种RTTI机制,您可以处理失败。此外,这与模板无关。