Link to home
Start Free TrialLog in
Avatar of Zulma9999
Zulma9999

asked on

namespace requirement inside class member function

What is the namespace requirement inside class member function?

namespace WinX_Namespace
{
     class Widget{
     public:
           bool Function(){return false;};
     };
}

class foo : public WinX_Namespace::Widget
{
public:
 bool Function();
};

//In cpp file
bool foo::Function()
{
 return Widget::Function();//Does this need namespace
}


Does the function call to Widget::Function also need the namespace WinX_Namespace.

I can compile the above code to VC++ with no problem, but it will not compile in an Apex C++ compiler.

If I change the code like this
bool foo::Function()
{
 return WinX_Namespace::Widget::Function();
}
Then it will compile in the Apex compiler, but it does not compile in the VC++ compiler.

The VC++ compiler gives me this error
error C2352: 'WinX_Namespace::Widget::Function' : illegal call of non-static member function

So occurring to the C++ standards, which one of these method are right, and which one is wrong?
Avatar of Axter
Axter
Flag of United States of America image

Technically speaking, both methods should have been able to compile, so I would say they're both wrong.
>>error C2352: 'WinX_Namespace::Widget::Function' : illegal call of non-static member function

The compiler is absolutely correct about this:

bool foo::Function()
{
return WinX_Namespace::Widget::Function();
}

bool foo::Function()
{
return Widget::Function();
}

are both calls to a nonstatic member of "Widget". You probably wanted to use

bool foo::Function()
{
WinX_Namespace::Widget w;
return w.Function();
}

or

bool foo::Function()
{
Widget w;
return w.Function();
}

respectively.
>>re both calls to a nonstatic member of "Widget". You >>probably wanted to use

According to the questioner's code, these are calls to the parrent function.  Remember foo is a decedent of Widget.
So calling Widget::Function(), should call the parrent function.

Moreover, you can accomplish the same thing by calling ::Function(), which should also compile on both compilers.
Avatar of Zulma9999
Zulma9999

ASKER

jkr,
No, I don't want to call a new instance of Widget.  I want to call the base class member function.
Axter,
>>Moreover, you can accomplish the same thing by
>>calling ::Function(), which should also compile on both
>>compilers.

In the example I posted, this could fix the problem, but what if I have to parent classes with the same Function name, and I want to specify which base class function I want to use?

namespace WinX_Namespace
{
     class Widget1{
     public:
           bool Function(){return false;};
     };
     class Widget2{
     public:
           bool Function(){return true;};
     };
}

class foo : public WinX_Namespace::Widget1, WinX_Namespace::Widget2
{
public:
 bool Function1();
 bool Function2();
};

//In cpp file
bool foo::Function1()
{
 return Widget1::Function();
}

//In cpp file
bool foo::Function2()
{
 return Widget2::Function();
}

Now I can't use ::Function call because the compiler is not going to know which one to pick.
In this case, you can try adding using namespace to your function.
Example:
bool foo::Function1()
{
     using namespace WinX_Namespace;
     return Widget1::Function();
}

That should make both VC++ happy and Apex happy.
>>In this case, you can try adding using namespace to your
>>function.
That method would pull everything in the namespace, which I don't want to do.
I'm sorry to be so picky, but I'm trying to port some code, and I want to make sure it comes out right.

namespace WinX_Namespace
{
     class Widget1{
     public:
          bool Function(){return false;};
     };
     class Widget2{
     public:
          bool Function(){return true;};
     };
     bool SomeXFunction(){return false;}
}

bool SomeXFunction()
{
     return true;
}

class foo : public WinX_Namespace::Widget1, WinX_Namespace::Widget2
{
public:
     bool Function1();
     bool Function2();
};

//In cpp file
bool foo::Function1()
{
     using namespace WinX_Namespace;
     bool x = SomeXFunction(); //Error here
     return Widget1::Function();
}

If I use your method I get this error from VC++
error C2668: 'SomeXFunction' : ambiguous call to overloaded function
Ok, this is not going to be pretty, but it's the only method I can think of which will let your code compile on both compilers correctly.

When calling the base function, wrap {} around the function, and inside the {}, and before the function call, add a using namespace.
The curly cues will prevent the using namespace from pulling everything in the namespace into the entire function.  The using namespace stays within side of the scope of the curly cues {}
Example:

namespace WinX_Namespace
{
     class Widget1{
     public:
          bool Function(){return false;};
     };
     class Widget2{
     public:
          bool Function(){return true;};
     };
     bool SomeXFunction(){return false;}
}

bool SomeXFunction()
{
     return true;
}

class foo : public WinX_Namespace::Widget1, WinX_Namespace::Widget2
{
public:
     bool Function1();
     bool Function2();
};

//In cpp file
bool foo::Function1()
{
     bool x = SomeXFunction();
     {
          using namespace WinX_Namespace;
          if (x) return Widget1::Function();
     }
     SomeXFunction();
     WinX_Namespace::SomeXFunction();
     {
          using namespace WinX_Namespace;
          return Widget1::Function();
     }
}

//In cpp file
bool foo::Function2()
{
     bool x = SomeXFunction();
     {
          using namespace WinX_Namespace;
          if (x) return Widget2::Function();
     }
     SomeXFunction();
     WinX_Namespace::SomeXFunction();
     {
          using namespace WinX_Namespace;
          return Widget2::Function();
     }
}

Axter,
That works, but I like to keep this question open to see if any one else has a better method.
what does your Apex compiler say about the following, VC doesnt complain..

namespace WinX_Namespace
{
    class Widget1{
    public:
          bool Function(){return false;};
    };

    class Widget2{
    public:
          bool Function(){return false;};
    };
}

typedef WinX_Namespace::Widget1 wid1;
typedef WinX_Namespace::Widget2 wid2;

class foo : public wid1, public wid2
{
public:
bool Function();
};

//In cpp file
bool foo::Function()
{
     wid1::Function();
     return wid2::Function();
}

ambience,
Good try, but that puts wid1 & wid2 into the global namespace.  I'm trying to keep object in WinX_Namespace out of the global namespace.
ASKER CERTIFIED SOLUTION
Avatar of Axter
Axter
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Axter is right, in fact i anticipated that issue .. and i think i was going to suggest the same as Axter has mentioned.

Axter, i tried that

class foo : public WinX_Namespace::Widget1, public WinX_Namespace::Widget2
{
     typedef WinX_Namespace::Widget1 wid1;
     typedef WinX_Namespace::Widget2 wid2;
public:
bool Function();
};

and it compiled fine on VC++, no issues.
>>and it compiled fine on VC++, no issues.

Yes, it'll compile the way you have it, but the example I posted does not rename the base class.
It uses the same name, so you don't have to use a different name in your decedent class implementation.

That should fource the Apex compiler to work just like the VC++ compiler, in accepting code using just the class name with out the namespace.
ambience, I posted additional points for you.

https://www.experts-exchange.com/jsp/qManageQuestion.jsp?ta=cplusprog&qid=20323276


Thank you both for your help, and sorry it took me so long to get back to this question.