【问题标题】:Why are some functions within my template class not getting compiled?为什么我的模板类中的某些函数没有被编译?
【发布时间】:2014-07-03 23:26:25
【问题描述】:

我正在使用 VS Express 2013 试图编译一个 c++ 项目。我创建了一个带有一些功能的模板类。该类及其函数都在一个头文件中。我已经包含了这个文件,我已经使用了这个类,我已经从中调用了函数,尽管 Visual Studio 不会编译我没有使用的类的函数。我已经关闭了所有优化。我是否必须使用我编写的函数来查看它是否编译?

函数如下:

void remove(ID id)
{
    sdfgsdfg456456456456sfdsdf
}

该函数不应编译。如果我确实使用这个函数,项目确实不会编译,但如果我不使用这个函数,项目将编译,即使我使用这个类中的其他函数。

有解决办法吗?如果我在 .cpp 文件中实现该功能,会发生同样的事情吗?

编辑:我没有提到它是一个模板类。我已经在其中添加了该信息。

【问题讨论】:

  • 你是在调试配置中编译,还是在发布配置中编译?
  • 在发布配置中。
  • 在调试配置中编译时会发生同样的事情吗?
  • 那就是答案;除非某些东西实际引用它,否则不会实例化模板代码。显然,当你实例化一个模板类时,它只会实例化你使用的成员函数(我可以重现这个)。
  • @user1594138 请更新您的问题以反映现实。在这方面,模板函数的工作方式与普通函数非常不同。您还应该清楚地说明您的代码在哪个文件中,因此毫无疑问您的代码是否分布在许多文件中,以及代码是否在您实际使用/包含的头文件中。

标签: c++ visual-studio templates visual-studio-2013


【解决方案1】:

正如 cmets 所揭示的,发生这种情况的原因是因为 remove() 是类模板中的一个函数。编译器只有在实际使用时才实例化模板代码;如果你不打电话给remove(),它可能会出现你想要的所有语法错误,没有人会抱怨。

更正式地说,标准状态的第 14.7.1 节(强调我的):

类模板特化的隐式实例化导致 声明的隐式实例化,但不是 类成员函数的定义或默认参数

稍后在同一部分:

实现不应隐式实例化函数 模板,成员模板,非虚拟成员函数,成员 类或类模板的静态数据成员 需要实例化。

(此处“隐式”一词是关键;如果您使用explicit template instantiation,编译器将立即尝试使用指示的类型实例化所有成员,如果有任何未编译则失败)

这不仅仅是优化;您可以利用此行为来实例化具有仅支持模板操作子集的类型的类模板。例如,假设您编写了一个模板类,它将与支持bar() 操作的类型一起使用,此外,有些还支持baz()。你可以这样做:

template<typename T>
class Foo
{
private:
   T _myT;

public:
   void bar()
   {
      _myT.bar();
   }

   void baz()
   {
      _myT.baz();
   }
};

现在假设你也有这些:

struct BarAndBaz
{
   void bar() {}
   void baz() {}
};

struct BarOnly
{
   void bar() {}
};

这将编译并运行得很好:

void f()
{
   Foo<BarAndBaz> foo1;
   foo1.bar();
   foo1.baz();

   Foo<BarOnly> foo2;
   foo2.bar();
   // don't try foo2.baz()!
   // or template class Foo<BarOnly>!
}

【讨论】:

  • 可能值得一提的是显式实例化,它将立即尝试实例化所有成员函数。语法是template class Foo&lt;int&gt;;
  • @MooingDuck 这似乎是一个值得的补充;已编辑
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多