如何让两个模板化的类可以隐式地相互转换

时间:2014-08-26 14:53:42

标签: c++ templates visual-c++ c++11

我最近遇到一种情况,导致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;
}

我猜测错误正在发生,因为每个类在其定义中引用了另一个定义,因此存在无限的递归深度;但是,我不知道如何解决这个问题,因为我只能在内联中定义模板;我无法声明它们然后在其他地方定义它们(当两个模板都已声明并且内部相互暴露时)。

1 个答案:

答案 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;
}