BUG: ATL consumer templates do not compile when you use the CArrayRowset class in Visual C++ .NET or in Visual C++ 2005 (828558)



The information in this article applies to:

  • Microsoft Visual C++ 2005 Express Edition
  • Microsoft Visual C++ .NET (2003)
  • Microsoft Visual C++ .NET (2002)

SYMPTOMS

The CCommand class of Microsoft ATL (Active Template Library) provides methods to set a command and to execute a command. However, in the CCommand ATL consumer template, when you define the TRowset parameter as CArrayRowset, and you use Microsoft Visual C++ .NET or Microsoft Visual C++ 2005 to compile your code, you may receive following compiler error message:
error C3200: 'ATL::CArrayRowset<TAccessor>' : invalid template argument for template parameter 'TRowset', expected a class template
with
[
TAccessor=CUserDataAccessor
]
see reference to class template instantiation 'ATL::CCommand<TAccessor,TRowset>' being compiled
with
[
TAccessor=ATL::CAccessor<CUserDataAccessor>,
TRowset=ATL::CArrayRowset<CUserDataAccessor>
]
Note In Microsoft Visual C++ 6.0, you do not receive this compiler error.

WORKAROUND

To work around this problem, change the definition of the CCommand ATL consumer template from the following
CCommand< CAccessor<CUserDataAcc>, CArrayRowset<CUserDataAcc> > cmd;
to the following:
CCommand< CAccessor<CUserDataAccessor>, CArrayRowset > cmd;
To do this, follow these steps:
  1. In Solution Explorer, double-click ATLCommand.cpp under the Source Files folder.
  2. Locate the following code in the main function:
    CCommand< CAccessor<CUserDataAccessor>, CArrayRowset<CUserDataAccessor> > cmd;
  3. Replace the code that you located in step 2 with the following code:
    // This definition is broken in Visual Studio .NET 2002 and in Visual Studio .NET 2003.
    // CCommand< CAccessor<CUserDataAccessor>, CArrayRowset<CUserDataAccessor> > cmd;
    // The following statement represents the workaround:
    CCommand< CAccessor<CUserDataAccessor>, CArrayRowset > cmd;
  4. Press the CTRL+SHIFT+B key combination to build the code.

    Notice that the code compiles without any errors.

STATUS

Microsoft has confirmed that this is a bug in the Microsoft products that are listed at the beginning of this article.

MORE INFORMATION

Steps to Reproduce the Behavior

  1. Start Microsoft Visual C++ 6.0.
  2. On the File menu, click New, and then click Win32 Console Application on the Projects tab of the New dialog box.
  3. In the Project name text box, type ATLCommand, and then click OK.
  4. In the Win32 Console Application - Step 1 of 1 dialog box, click to select A "Hello, World" Application., and then click Finish.
  5. Click OK in the New Project Information dialog box.
  6. Verify that the Workspace window is visible. If this window is not visible, press ALT+0.
  7. In the Workspace window, double-click ATLCommand.cpp under Source Files.
  8. Replace all the code in the ATLCommand.cpp file with the following code:
    #include "stdafx.h"
    
    #define UNICODE
    #define _UNICODE
    
    #pragma pack(push, 1)
    #include <atldbcli.h>
    #pragma pack(pop)
    
    #include <oledberr.h>
    #include <atlbase.h>
    #include <iostream>
    
    #define DBINITCONSTANTS
    
    using namespace std;
    
    class CUserData
    {
    public:
        TCHAR m_UserName[64];
        double m_CardNo;
        LONG m_PinNo;
        BYTE m_UserEnabled;
        BYTE m_UserGroup;
        LONG m_UserNum;
        LONG m_UserOptions;
    };
    
    class CUserDataAccessor : public CUserData 
    {
        public:
    
        BEGIN_COLUMN_MAP(CUserDataAccessor)
                COLUMN_ENTRY(1, m_UserName)
                COLUMN_ENTRY(2, m_CardNo)
                COLUMN_ENTRY(3, m_PinNo)
                COLUMN_ENTRY(4, m_UserEnabled)
                COLUMN_ENTRY(5, m_UserGroup)
                COLUMN_ENTRY(6, m_UserNum)
                COLUMN_ENTRY(7, m_UserOptions)
        END_COLUMN_MAP()
        
    };
    
    
    int main(int argc, char* argv[])
    {
        USES_CONVERSION;
        
        CoInitialize(NULL);
    
        //HRESULT hr;
        CDataSource ds;
        CSession session;
        CCommand< CAccessor<CUserDataAccessor>, CArrayRowset<CUserDataAccessor> > cmd;
        CoUninitialize();
        return 0;
    }
  9. Press F7 to build the application.

    The code compiles without any errors, and the ATLCommand.exe file is built.
  10. Quit Visual C++ 6.0.
  11. Start Microsoft Visual Studio .NET or Microsoft Visual Studio 2005.
  12. On the File menu, point to Open, and then click Project.
  13. In the Open Project dialog box, locate the folder that contains the files of the application that you created in step 5.
  14. In the Files of type list, click Compatible Workspace Files.
  15. In the Open Project dialog box, click ATLCommand, and then click Open.
  16. In the Visual C++ Project dialog box, click Yes to convert and to open this project.
  17. Press the CTRL+SHIFT+B key combination to build the solution.

    You receive the compilation error that is mentioned in the "Symptoms" section of this article.

REFERENCES

For more information about the CCommand class, visit the following Microsoft Web site:For more information about the CArrayRowset class, visit the following Microsoft Web site:

Modification Type:MajorLast Reviewed:1/12/2006
Keywords:kbtemplate kbbug KB828558 kbAudDeveloper