【问题标题】:How to get two templated classes implicitly convertible to one another如何让两个模板类可隐式转换为彼此
【发布时间】: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 &lt;typename U&gt; friend class Foo&lt;U&gt;; 是非法的,据我所知。您可以改用 friend class Foo&lt;T&gt;;,这需要前向声明。
  • @Shaktal 我使用了 Visual Studio 2012 更新 4。它正确报告最终文件中首先出现的类取决于尚未定义的内容。这可能是编译器如何报告错误的错误,但这段代码不应该按原样工作。
  • @pqnet #pragma once 毫无用处,并得到many compilers 的支持。

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


【解决方案1】:

您必须对模板类使用前向声明。示例:

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

【讨论】:

  • 是否可以将Foo&lt;T&gt;Bar&lt;U&gt; 作为TU 的所有可能组合的朋友类? IE。 Foo&lt;float&gt;Bar&lt;int&gt; 的朋友吗?
  • 是的,你说的是template&lt;typename U&gt; friend class Foo;(注意不是Foo&lt;U&gt;)。
  • @Shaktal 对不起,我猜错了你想做什么。更新
  • @n.m.和 pqnet:非常感谢您的帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多