“Dependent Name不是Type”,但前缀为“typename”会导致编译器崩溃

时间:2013-07-16 18:47:25

标签: c++ visual-c++ visual-studio-2012

请在休息后查看更新的代码;

我有以下模板类:

template<class T> class CDFAManListOps
{
    static std::list<T>::iterator CDFAManListOps::GetIterator(std::list<T>* list, int pId)
    {
    }
}

当我尝试编译它时,它说

std::list<T>::iterator' : dependent name is not a type 1> prefix with 'typename' to indicate a type

但是,如果我像编译器那样更改函数请求:

static typename std::list<T>::iterator CDFAManListOps::GetIterator(std::list<T>* list, int pId)

编译器(VS12)因以下错误崩溃:

fatal error C1001: An internal error has occurred in the compiler.

1> (compiler file 'msc1.cpp', line 1443)

1> To work around this problem, try simplifying or changing the program near the locations listed above.

知道这段代码有什么问题吗?


UPDATE:这是我可以获得的最少量代码的全部内容,可以重现此次崩溃。

#include <list>

template<class T> class CDFAManListOps
{
    static typename std::list<T>::iterator CDFAManListOps::GetIterator(std::list<T>* list, int pId)
    {
    }

    static typename std::list<T>::iterator CDFAManListOps::GetIterator(std::list<T>* list, T object)
    {

    }
};

int main()
{

}

如果我取出两个GetIterator函数中的 EITHER ,程序将编译并运行正常。只有当存在BOTH函数时,编译器才会崩溃。这是否更清楚我的代码中的问题是什么?

(此外,如果有人想跟上其状态,我将向Microsoft Connect提交错误报告并在此处发布链接。)

我已在Microsoft Connect here上提交了错误报告。

更新:在可预见的未来,Microsoft已决定对此特定错误采取任何措施。请参阅上面的Microsoft Connect链接。

2 个答案:

答案 0 :(得分:4)

我无法使用MSVS2012中的给定代码重现您的问题。 编译好了:

#include <list>
template<class T> 
class CDFAManListOps
{
public:
  static typename std::list<T>::iterator GetIterator(std::list<T>* list, size_t pId)
  {
    typename std::list<T>::iterator it = list->begin();
    for (size_t i=0; i<pId; ++i) ++it;
    return it;
  }
};

int main(void)
{
  std::list<size_t> x(5);
  CDFAManListOps<size_t>::GetIterator(&x, 2);
  return 0;
}

好的,我现在可以重现这个问题。从类内定义中删除CDFAManListOps::将导致正确编译代码。

#include <list>
template<class T> class CDFAManListOps
{
    static typename std::list<T>::iterator GetIterator(std::list<T>* list, int pId) {}
    static typename std::list<T>::iterator GetIterator(std::list<T>* list, T object) {}
};
int main() {}

答案 1 :(得分:0)

作为一种解决方法,在函数声明之前尝试typedef迭代器类型作为类成员:

template<class T> class CDFAManListOps
{
    typedef typename std::list<T>::iterator iter_t;
    static iter_t GetIterator(std::list<T>* list, int pId)
    {
    }
};

或完全指定列表类型:

template<class T> class CDFAManListOps
{
    template <typename Allocator>
    static typename std::list<T, Allocator>::iterator GetIterator(std::list<T, Allocator>* list, int pId)
    {
    }
};