为什么我的模板类中的某些函数没有被编译?

use*_*138 9 c++ templates visual-studio visual-studio-2013

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

这是功能:

void remove(ID id)
{
    sdfgsdfg456456456456sfdsdf
}
Run Code Online (Sandbox Code Playgroud)

该函数不应该编译.事实上,如果我使用这个函数,项目将无法编译,但如果我不使用该函数,项目将编译,即使我使用此类中的其他函数.

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

编辑:我忽略了提到它是一个模板类.我已经添加了这些信息.

dlf*_*dlf 11

正如评论中所揭示的那样,之所以发生这种情况,是因为它remove()是类模板中的一个函数.如果实际使用,编译器仅实例化模板代码; 如果你不打电话remove(),它可能会有你想要的所有语法错误,没有人会抱怨.

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

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

后来在同一部分:

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

("隐式"一词在这里是关键;如果使用显式模板实例化,编译器将立即尝试使用指示的类型实例化所有成员,如果没有编译则失败)

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

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

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

   void baz()
   {
      _myT.baz();
   }
};
Run Code Online (Sandbox Code Playgroud)

现在假设你也有这些:

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

struct BarOnly
{
   void bar() {}
};
Run Code Online (Sandbox Code Playgroud)

这将编译并运行正常:

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

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

  • 可能值得一提的是显式实例化,它会立即尝试实例化所有成员函数.语法是`template class Foo <int>;`. (2认同)