尝试从模板化函数返回向量会引发编译错误。

Posted

技术标签:

【中文标题】尝试从模板化函数返回向量会引发编译错误。【英文标题】:Trying to return a vector from a templated function throws compiling errors. 【发布时间】:2012-10-02 01:47:30 【问题描述】:

问题如下:以下测试抛出大量编译错误。

#include <vector>
using namespace std;

template<class T>
class test
   vector<T> vec;
public:
   vector<T>::iterator begin();

;

template<class T>
vector<T>::iterator test<T>::begin()
  return vec.begin();


int main()

  test<float> testing;
  testing.begin();


一些编译器错误:

 test.cpp(8): warning C4346: 'std::vector<T>::iterator' : dependent name is not a type
 test.cpp(8): error C2146: syntax error : missing ';' before identifier 'begin'
 test.cpp(13): error C2143: syntax error : missing ';' before 'test<T>::begin'

但是,如果您将模板化的vector&lt;T&gt; 换成vector&lt;float&gt;,它的编译就很好了。例如:

template<class T>
class test
   vector<T> vec;
public:
   vector<float>::iterator begin();

;

template<class T>
vector<float>::iterator test<T>::begin()
   return vec.begin();

关于为什么的任何想法?

【问题讨论】:

【参考方案1】:

需要在两个地方添加typename

typename vector<T>::iterator begin();

typename vector<T>::iterator test<T>::begin()

通过添加typename,您告诉编译器如何解析代码。基本上,通过添加typename,您是在告诉编译器将声明解析为类型。

请阅读Where and why do I have to put the “template” and “typename” keywords? 以获得深入的解释。

【讨论】:

【参考方案2】:

您需要使用typename 关键字来区分vector&lt;T&gt;::iterator 指的是作用域类型,而不是作用域数据或函数成员:

template<class T>
class test
   vector<T> vec;
public:
   typename vector<T>::iterator begin();

;

template<class T>
typename vector<T>::iterator test<T>::begin()
  return vec.begin();

【讨论】:

一个成员——只是一个成员type,而不是一个成员变量。【参考方案3】:

在 C++ 模板类中,模板成员函数的主体必须在类内部定义,因为模板参数不存在于类外部。最后两个错误看起来像编译器在不熟悉的上下文导致它误解完全有效的语法时产生的错误。尝试在类中移动函数体。

【讨论】:

这不是真的。模板的定义必须在模板被实例化的地方可见,但不必在类声明中。 对不起。我正在考虑将模板拆分为多个文件。我的错。 不用担心,只是想澄清一下,这样没人会感到困惑。不过,为了清楚起见,您可能需要编辑/删除您的答案。

以上是关于尝试从模板化函数返回向量会引发编译错误。的主要内容,如果未能解决你的问题,请参考以下文章

当我使用标头时,C++ 函数会引发错误,但如果我在源代码中定义它则不会?

使用嵌套模板化变量解决 Visual Studio 内部编译器错误

编译器错误? g++ 允许可变大小的静态数组,除非函数是模板化的

编译期多态和Sfinae

各种坑

将模板参数传递给调用成员函数的函数