代码正确编译时,您能确定所有模板类型都正确吗?

时间:2015-06-15 12:28:16

标签: c++

因为在C ++中,当您使用模板时,在实例化之前不会生成代码。编译器只会为实例化类型生成代码。这是否意味着当我的代码(使用模板)编译时,我可以确定没有类型冲突,并且我的代码在运行时不会因类型错误而崩溃?

如果没有,有人可以提供一个示例,其中模板代码成功编译但仍然在运行时崩溃?

3 个答案:

答案 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机制,您可以处理失败。此外,这与模板无关。