0
votes

Environment

Visual Studio 2013 and C++/CLI.

The (ho/e)rror

I faced a situation of IntelliSense giving error on a compiler compliant row. Thus a false positive.

The error is the following:

IntelliSense: function "< full qualified method name >" cannot be called with the given argument list
argument types are:
< expected argument type >
object type is:
< object type >

What happened

I made a UserControl. There I declared a custom event with relative delegate. I created a form. In form constructor I alloc a my user control instance and try to attach a form method to the control custom event.

Compiler says everything is ok. IntelliSense tells me that event attachment mismatches types.

How to reproduce

I digged in the problem and created an essential context that should reproduce the problem:

  1. Create a solution with two projects: FavaTest (as ClassLibrary) and FavaForm (as Console application...or whatever).
  2. In FavaTest create a UserControl whose name is FavaClass and paste the following in FavaClass.h.

    #pragma once

    using namespace System;
    using namespace System::ComponentModel;
    using namespace System::Collections;
    using namespace System::Windows::Forms;
    using namespace System::Data;
    using namespace System::Drawing;


    namespace FavaTest {

        public ref class FavaClass : public System::Windows::Forms::UserControl
        {
        public:
            FavaClass(void)
            {
                InitializeComponent();
            }

            // -- here defines very simple event --
            delegate void FavaDelegate();
            event FavaDelegate^ FavaEvent;

        protected:
            ~FavaClass()
            {
                if (components)
                {
                    delete components;
                }
            }

        private:
            System::ComponentModel::Container ^components;

    #pragma region Windows Form Designer generated code
            void InitializeComponent(void)
            {
                this->SuspendLayout();
                // 
                // FavaClass
                // 
                this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
                this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
                this->Name = L"FavaClass";
                this->Size = System::Drawing::Size(249, 147);
                this->ResumeLayout(false);

            }
    #pragma endregion
        };
    }

  1. In project FavaForm create a Form whose name is LaForm and paste the following in LaForm.h

    namespace FavaForm {

        using namespace System;
        using namespace System::ComponentModel;
        using namespace System::Collections;
        using namespace System::Windows::Forms;
        using namespace System::Data;
        using namespace System::Drawing;

        public ref class LaForm : public System::Windows::Forms::Form
        {
        public:
            LaForm(void)
            {
                InitializeComponent();

                // here simply allocs a FavaClass object and try to attach to FavaEvent event
                FavaTest::FavaClass ^item = gcnew FavaTest::FavaClass();
                item->FavaEvent += gcnew FavaTest::FavaClass::FavaDelegate(this, &LaForm::onfava);
            }

            void onfava(){}

        protected:
            ~LaForm()
            {
                if (components)
                {
                    delete components;
                }
            }
        private:
            System::ComponentModel::Container ^components;

    #pragma region Windows Form Designer generated code
            void InitializeComponent(void)
            {
                this->SuspendLayout();
                // 
                // LaForm
                // 
                this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
                this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
                this->ClientSize = System::Drawing::Size(368, 261);
                this->Name = L"LaForm";
                this->Text = L"LaForm";
                this->ResumeLayout(false);

            }
    #pragma endregion
        };
    }

  1. Build FavaTest
  2. In FavaForm project common properties add a new reference to FavaTest in order to use its generated dll as a dependencie
  3. Build solution.

Now, while the compiler heralds everything is fine, you should see that IntelliSense complains something on the event attachment row, with the following errore message:

IntelliSense: function "FavaTest::FavaClass::FavaEvent::add" cannot be called with the given argument list
    argument types are:
(FavaTest::FavaClass::FavaDelegate ^)
    object type is: FavaTest::FavaClass ^

Ready to run package

I packaged all this in a side-test-standalone-solution zip file in order to make it possibile to unzip and run, but unfortunately (IMHO also questionably) I cannot post it here dued to SE guidelines, so it's up to you to make the debug context according to the above.

The question

I could also be missing something, but I used several times this algorithm before and it worked perfectly, now I'm experiencing this on two different machines (VS2013 and VS2015). Does this error apply to you too? And what's wrong with IntelliSense? It is such a simple scenario that I can't imagine I'm the only one experiencing it. I found no clue on the Internet though.

1
No intelisense warning with VS2012. However, Code Analysis complains about improper event declaration: see "msdn.microsoft.com/en-us/library/ms182133%28v=vs.120%29.aspx".Sebacote
@SébastienCôté excuse me, but the link you provided is broken...TechNyquist
Unfortunately I tried to put the two parameters that the article suggests and nothing changes. Can't get rid of it...TechNyquist

1 Answers

0
votes

Solved.

It came out that in order to avoid IntelliSense to get crazy, the delegate definition has to be out of the event parent class scope. So in my situation all I had to do to get things right (for IntelliSense) was to move delegate outside the class adding the public keyword, such as:

namespace FavaTest
{

    public delegate void FavaDelegate();    // moved out of the class with "public"

    public ref class FavaClass : public System::Windows::Forms::UserControl
    {
        public:
            [...]

            // -- here defines very simple event --
            // delegate row away from here
            event FavaDelegate^ FavaEvent;

            [...]
    }
}