我最近遇到一种情况,导致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;
}
我猜测错误正在发生,因为每个类在其定义中引用了另一个定义,因此存在无限的递归深度;但是,我不知道如何解决这个问题,因为我只能在内联中定义模板;我无法声明它们然后在其他地方定义它们(当两个模板都已声明并且内部相互暴露时)。
答案 0 :(得分:2)
您必须为模板类使用前向声明。例如:
template <typename T>
class Foo;
template <typename T>
class Bar {
template <class U>
friend class Foo;
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:
T m_tArray[5];
};
template <typename T>
class Foo {
template <class U>
friend class Bar;
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:
T m_tArray[5];
};
int main() {
Foo<int> foo;
}