Observe this code:

        TOOLBARINFO tbi = { 0 };
        BUTTONINFO bi, *xBI;
        tbi.pTOI = pTOI;
        int x = 0, xSearchBox = 0, s = 0;
        BYTE xType = btNone;
        BOOL bAdd;

        for( ;*pszInfo; )
        {
            bAdd = TRUE;
            memset(&bi, 0, sizeof bi);
            switch( *pszInfo )
            {
                case bfButton:
                    s++;
                    bi.L = x + 4;
                    if( xType==bfButton )
                        bi.L += 4;
                    bi.R = bi.L + 24;
                    bi.wFlags = xType = bfButton;

                    if( *(pszInfo+1) )
                    {
                        *++pszInfo;
                        for( ;*(pszInfo+1) && bfActive<=*(pszInfo+1) && *(pszInfo+1)<=bfDisabled;*pszInfo++ )
                            bi.wFlags |= *pszInfo;
                        if( *pszInfo && *pszInfo==':' )
                        {
                            *++pszInfo;
                            _rgTipText.Add(pszInfo);
                        }
                    }
                    break;
                case bfSeparator:
                    bi.L = x + 4;
                    bi.R = x + 6;
                    bi.wFlags = xType = bfSeparator;
                    break;
                case bfLabel:
                {
                    int cx = 0;
                    if( *++pszInfo=='*' )
                        cx = pTOI->DoToolbarOwnerAction(WM_MEASUREITEM, tbi.rgButtons.GetSize(), 0);
                    else
                        cx = _wtoi(pszInfo);
                    bi.wFlags = xType = bfLabel;
                    bi.L = x + 4;
                    bi.R = bi.L + cx;
                    break;
                }
                case bfDropdown:
                    ASSERT(xBI!=NULL);
                    xBI->wFlags |= bfDropdown;
                    bi.L = x;
                    bi.R = x + 5;
                    bi.wFlags = xType = bfDropdown;
                    break;
                case bfSearchBox:
                    bAdd = FALSE;
                    xSearchBox = tbi.rgButtons.GetSize();
                    xType = bfSearchBox;
                    x = -30000;
            }

            if( bAdd )
            {
                x = bi.R;
                if( xSearchBox )
                    tbi.cxRights += (bi.R - bi.L) + 4;
                tbi.rgButtons.Add(bi);
                if( xType==bfButton )
                    xBI = &tbi.rgButtons[tbi.rgButtons.GetSize()-1];
                else
                    xBI = NULL;
            }
            pszInfo += wcslen(pszInfo) + 1;
        }

        if( tbi.rgButtons.GetSize() )
        {
            tbi.xSearchBox = xSearchBox;
            if( pTOI->hbmIco==HBMDEFAULT )
                pTOI->hbmIco = _hbmStdToolbarIco;

            if( xSearchBox )
            {
                RECT rc;
                HWND hwnd = NULL;
                GetClientRect(m_hWnd, &rc);

                rc.left = tbi.rgButtons[xSearchBox-1].R + 4;
                rc.top = 32;
                rc.right -= (rc.left + tbi.cxRights + 8);
                rc.bottom = (long)&tbi.hwndSearch;

                if( !pTOI->DoToolbarOwnerAction(WM_CREATE, 0, (WPARAM)&rc) )
                {
                    tbi.hwndSearch = CreateWindow(L"edit", 0, WS_CHILD|WS_VISIBLE|ES_AUTOHSCROLL|WS_BORDER,
                        rc.left, 6, rc.right - xSearchBox, 20,
                        m_hWnd, (HMENU)1, theApp.m_hInstance, 0);
                    Edit_LimitText(tbi.hwndSearch, MAX_PATH);
                    SetWindowFont(tbi.hwndSearch, (HFONT)GetStockObject(DEFAULT_GUI_FONT), TRUE);
                    SendMessage(tbi.hwndSearch, EM_SETCUEBANNER, TRUE, (LPARAM)L"Enter text to search");
                }

                x = rc.left + rc.right - 12;
                int cx;
                for( s=xSearchBox;s<(int)tbi.rgButtons.GetSize();s++ )
                {
                    BUTTONINFO & bi = tbi.rgButtons[s];
                    cx = bi.R - bi.L;
                    if( bi.wFlags!=bfDropdown )
                        x += 4;
                    bi.L = x;
                    x = bi.R = x + cx;
                }
            }

            _rgTBI.Add(tbi);
            _pTBI = &_rgTBI[_rgTBI.GetSize()-1];
        }
    }

_rgTBI is declared as CArray<TOOLBARINFO> _rgTBI;.
TOOLBARINFO is a struct where rgButtons is a member which is declared as CArray<BUTTONINFO rgButtons.
Calling the Add() of CArray in rgButtons works without any problem. But when I called the same method in _rgTBI, the compiler gave me the following error:

f:\program files\microsoft visual studio 10.0\vc\atlmfc\include\afxtempl.h(262): error C2248: 'CObject::operator =' : cannot access private member declared in class 'CObject'
1>          f:\program files\microsoft visual studio 10.0\vc\atlmfc\include\afx.h(536) : see declaration of 'CObject::operator ='
1>          f:\program files\microsoft visual studio 10.0\vc\atlmfc\include\afx.h(510) : see declaration of 'CObject'
1>          This diagnostic occurred in the compiler generated function 'CArray<TYPE> &CArray<TYPE>::operator =(const CArray<TYPE> &)'
1>          with
1>          [
1>              TYPE=BUTTONINFO
1>          ]

Now I no longer know where to start to fix this problem.

...and while I was waiting for someone to share any ideas, I discovered the culprit.

First, this one will not give you any problem:

struct SomeStruct
{
    int anIntMember;
    long aLongMember;
};

CArray<SomeStruct> some;

This one too will not give you any problem:

CArray<int> someInts;

But this one will:

struct AnotherStruct
{
    char firstMember;
    int secondMember;
    CArray<long> obviouslyAnArray;
}

Well, I just don't know if I am the only one who encountered this problem. I never had it using std::vector though.

This article has been dead for over six months. Start a new discussion instead.