"for" 循环中使用的复制构造函数,但是在哪里?

Copy constructor used in a "for" loop, but where?

我正在编写一个 UTF-8 字符串 class,它是两个常量和非常量迭代器 class。我遇到了一个常量问题。这是 classes :

class Utf8String
{
public:

   class ConstIter;

   class Iter
   {
      friend class ConstIter;

   private:

      Iter();

   private:

      Utf8String * m_pStr;

      utf8::iterator< char * > m_oIter;

   public:

      Iter( const Iter & );

      inline explicit Iter( Utf8String * pStr )
       : m_pStr( pStr )
       , m_oIter( m_pStr->m_sBuf, m_pStr->m_sBuf, m_pStr->m_sBuf + m_pStr->m_nSize )
      { }

      inline Iter & operator = ( const Iter & oIter )
      {
         m_pStr = oIter.m_pStr;
         m_oIter = utf8::iterator< char * >(
            m_pStr->m_sBuf,
            m_pStr->m_sBuf,
            m_pStr->m_sBuf + m_pStr->m_nSize );

         return *this;
      }

      inline operator const char * () const
      {
         return m_oIter.base();
      }

      inline uchar32_t operator * () const
      {
         return *m_oIter;
      }

      inline Iter & operator ++ ()
      {
         ++m_oIter;
         return *this;
      }

      inline Iter & operator -- ()
      {
         --m_oIter;
         return *this;
      }

      inline bool operator == ( const Iter & oIter )
      {
         return m_oIter == oIter.m_oIter;
      }

      inline bool operator != ( const Iter & oIter )
      {
         return m_oIter != oIter.m_oIter;
      }
   };

   class ConstIter
   {
   private:

      ConstIter();

   private:

      const Utf8String * m_pStr;

      utf8::iterator< const char * > m_oIter;

   public:

      ConstIter( const ConstIter & );

      inline ConstIter( const Iter & oIter )
       : m_pStr( oIter.m_pStr )
       , m_oIter( m_pStr->m_sBuf, m_pStr->m_sBuf, m_pStr->m_sBuf + m_pStr->m_nSize )
      { }

      inline ConstIter( const Utf8String * pStr )
       : m_pStr( pStr )
       , m_oIter( m_pStr->m_sBuf, m_pStr->m_sBuf, m_pStr->m_sBuf + m_pStr->m_nSize )
      { }

      inline operator const char * () const
      {
         return m_oIter.base();
      }

      inline ConstIter & operator = ( const ConstIter & oIter )
      {
         m_pStr = oIter.m_pStr;
         m_oIter = utf8::iterator< const char * >(
            oIter.m_pStr->m_sBuf,
            oIter.m_pStr->m_sBuf,
            oIter.m_pStr->m_sBuf + oIter.m_pStr->m_nSize );

         return *this;
      }

      inline ConstIter & operator = ( const Iter & oIter )
      {
         m_pStr = oIter.m_pStr;
         m_oIter = utf8::iterator< const char * >(
            m_pStr->m_sBuf,
            m_pStr->m_sBuf,
            m_pStr->m_sBuf + m_pStr->m_nSize );

         return *this;
      }

      inline uchar32_t operator * () const
      {
         return *m_oIter;
      }

      inline ConstIter & operator ++ ()
      {
         ++m_oIter;
         return *this;
      }

      inline ConstIter & operator -- ()
      {
         --m_oIter;
         return *this;
      }

      inline bool operator == ( const ConstIter & oIter )
      {
         return m_oIter == oIter.m_oIter;
      }

      inline bool operator != ( const ConstIter & oIter )
      {
         return m_oIter != oIter.m_oIter;
      }
   };

   // More stuff
};

我正在使用如下:

   Utf8String sStr = "not const";

   for( Utf8String::Iter i = sStr.Begin(); i != sStr.End(); ++i )
   {
   }

   // 2) Iterating over a const UTF-8 string :

   const Utf8String sConstStr = "const";

   for( Utf8String::ConstIter i = sConstStr.Begin(); i != sConstStr.End(); ++i )
   {
   }

   // 3) Const interators can also iterate over a non-const string :

   for( Utf8String::ConstIter i = sStr.Begin(); i != sStr.End(); ++i )
   {
   }

问题是,如果没有声明迭代器 classes 的复制构造函数 public,我会收到以下错误,尽管没有明确使用复制构造函数 :

Error   1   error C2248: 'core::Utf8String::Iter::Iter' : cannot access private member declared in class 'core::Utf8String::Iter'   c:\xxx\main.cpp 20

声明这些复制构造函数public解决问题。

会发生什么?编译器是将 Utf8String::ConstIter i = sStr.Begin() 优化为 Utf8String::ConstIter i( sStr.Begin() ) 还是进行其他一些隐式优化?

感谢您的帮助。 :)

编辑:使用 VS2005,不使用 C++11。

Utf8String::ConstIter i = sStr.Begin(); 是一个 声明 和一个 初始化 。它不是作业。此初始化是使用复制构造函数完成的。