为什么我的模板类中的一些函数不会被编译? [英] Why are some functions within my template class not getting compiled?

查看:152
本文介绍了为什么我的模板类中的一些函数不会被编译?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用VS Express 2013试图编译一个c ++项目。我创建了一个带有一些函数的模板类。类和它的函数都在一个头文件中。我已经包含了文件,我使用的类,我已经从它调用函数,尽管所有的视觉工作室不会编译类的功能,我不使用。我已关闭所有优化。



这是函数:

  void remove(ID id)
{
sdfgsdfg456456456456sfdsdf
}

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



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



编辑:我忽略了它是一个模板类。


解决方案

如评论中所示,发生这种情况的原因是 remove()是类模板中的一个函数。编译器只实例化模板代码(如果实际使用的话);如果你不调用 remove(),它可以有你想要的所有语法错误,没有人会抱怨。



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


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


稍后在同一节中:


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


(implicit这个词在这里很重要;如果使用 显式模板实例化,编译器将立即尝试使用指定的类型实例化所有成员,如果任何未编译则失败)



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

 模板< 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();
//不要尝试foo2.baz()!
//或模板类Foo< BarOnly> ;!
}


I am using VS Express 2013 trying to compile a c++ project. I've created a template class with some functions. The class and its functions are all in one header file. I've included the file, I've used the class, I've called functions from it, and despite all that visual studio won't compile the classes' functions that I'm not using. I've turned off all optimizations. Do I HAVE to use a function that I've written just to see that it compiles or not?

Here is the function:

void remove(ID id)
{
    sdfgsdfg456456456456sfdsdf
}

The function shouldn't compile. And indeed the project won't compile if I do use this function, but if I don't use the function the project will compile, even if I use other functions from within this class.

Is there a fix to this? Will the same thing happen if I implement the function in a .cpp file?

Edit: I neglected to mention it is a template class. I've added that information in.

解决方案

As revealed in comments, the reason this is happening is because remove() is a function in a class template. The compiler only instantiates template code if it is actually used; if you don't call remove(), it can have all the syntax errors you want and nobody will complain.

More formally, § 14.7.1 of the standard states (emphasis mine):

The implicit instantiation of a class template specialization causes the implicit instantiation of the declarations, but not the definitions or default arguments, of the class member functions

And later in the same section:

An implementation shall not implicitly instantiate a function template, a member template, a non-virtual member function, a member class, or a static data member of a class template that does not require instantiation.

(the word "implicit" is key here; if you use explicit template instantiation, the compiler will immediately try to instantiate all members using the indicated type(s) and fail if any doesn't compile)

This is not just an optimization; you can exploit this behavior to instantiate class templates with types that only support a subset of the template's operations. For example, suppose you write a template class that will be used with types that support a bar() operation, and in addition, some will also support baz(). You could do this:

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

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

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

Now suppose you have these too:

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

struct BarOnly
{
   void bar() {}
};

This will compile and run just fine:

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

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

这篇关于为什么我的模板类中的一些函数不会被编译?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆