【发布时间】:2014-08-26 14:53:41
【问题描述】:
我最近遇到了导致 Microsoft Visual Studio 2013 编译器产生内部错误 (C1001: An internal error has occured in the compiler.) 的情况。
如果我们有头文件Foo.h:
#pragma once
#ifndef FOO_H
#define FOO_H
#include "Bar.h"
template <typename T>
class Foo {
public:
operator Bar<T>() const
{
Bar<T> bar;
for( unsigned int i = 0; i < 5; ++i )
bar.m_tArray[i] = m_tArray[i];
return bar;
}
private:
template <typename U>
friend class Bar<U>;
T m_tArray[5];
};
#endif // FOO_H
还有Bar.h:
#pragma once
#ifndef BAR_H
#define BAR_H
#include "Foo.h"
template <typename T>
class Bar {
public:
operator Foo<T>() const
{
Foo<T> foo;
for( unsigned int i = 0; i < 5; ++i )
foo.m_tArray[i] = m_tArray[i];
return foo;
}
private:
template <typename U>
friend class Foo<U>;
T m_tArray[5];
};
#endif // BAR_H
然后我可以通过实例化任一类来引发错误,例如:
int main() {
Foo<int> foo;
}
我猜这个错误正在发生,因为每个类在它自己的定义中都引用了另一个类的定义,所以递归深度是无限的;但是,我不确定如何解决这个问题,因为我只能内联定义模板;我不能声明它们,然后在其他地方定义它们(当两个模板都被声明并且内部相互暴露时)。
【问题讨论】:
-
内部编译器错误(几乎)总是编译器中的错误。
-
是不是缺少前向声明?
-
template <typename U> friend class Foo<U>;是非法的,据我所知。您可以改用friend class Foo<T>;,这需要前向声明。 -
@Shaktal 我使用了 Visual Studio 2012 更新 4。它正确报告最终文件中首先出现的类取决于尚未定义的内容。这可能是编译器如何报告错误的错误,但这段代码不应该按原样工作。
-
@pqnet
#pragma once毫无用处,并得到many compilers 的支持。
标签: c++ templates visual-c++ c++11