tags:

views:

194

answers:

8

I want to define a class like this

class HttpRestAccessor
{
public:
    IResource& UpdateResource(string& , IResource& );
};

and implementing in cpp file

IResource& HttpRestAccessor::UpdateResource(string& resourceUri, IResource& resource)

this cpp file refers to Winbase.h which has defined UpdateResource as follows

#define UpdateResource  UpdateResourceW

And hence while compiling i get following error

error C2039: 'UpdateResourceW' : is not a member of 'RestToolkit::HttpRestAccessor'

this problem would be solved if rename function name to something different. but I would love to keep my function name as UpdateResource.

Thanks In Advance, Uday

+1  A: 

The simplest way is to include winbase.h before all other headers (in stdafx.h) so that you don't care whether the method name is replaced.

sharptooth
no, no, no. Any unfortunate user of this class would then end up with the same problem, even if they don't use winbase.h
Glen
+1: Good luck reaching 10k today :)
Binary Worrier
+4  A: 

Macro's totally ignore scope.

Basically the pre-precessor will do a find/replace of UpdateResource with UpdateResourceW so you're all out of luck.

renaming the method is your only option

Glen
+1 for renaming the method. The simplest and quickest way to solve the problem without "hacks"
Edison Gustavo Muenz
It's flat wrong to say renaming is the only option. Maybe the only non-hack option, but not the only option.
Matthew Flaschen
A: 

Ugh, that is the evil of the preprocessor!

A: 

you could use the #undef preprocessor directive to undefine the UpdateResource macro before you declare you function.

heavyd
Will work, but this needs to be done every time winbase.h is included (which is not always done directly) so it will be a lot of pain.
sharptooth
+6  A: 

Just undefine it:

 #undef UpdateResource

then redefine later if you actually need it.

EDIT: However, you should reconsider your aversion to renaming the method. As others have said, that's a more elegant solution.

Matthew Flaschen
This will have to be done prior to each inclusion of winbase.h which is not always done directly. Lots of pain.
sharptooth
Create function, winbasewrap.h, which does the undef and include. Find and replace your includes with this one.
Brian
I'm down voting this answer (specifically due to it's current success). Yes this will work but it's a particularly stinky "code smell". It's one of those clever tricks which over time will be forgotten until some poor maintainer spends 5 days trying to work out why code which used to compile no longer does.
Richard Corden
Richard, I wrote this answer because the OP specifically said "I would love to keep my function name as UpdateResource." I personally would prefer changing the name.
Matthew Flaschen
@Matthew: Ok, I can see now why you did this. However, I still think you're doing a disservice to the OP in this case. The solution is a huge hack for what has a much more sensible solution. I think providing answers that cover the question 100% should be secondary to providing answers that will reflect the "best solution". Given that you agreed with the renaming idea, maybe you could add a comment to your answer like: "this should only be used where renaming is simply not an option, rather than not desirable". BTW, I cannot return your vote, unless you edit the answer.
Richard Corden
+1  A: 

Rename your function. If you want to use windows libraries then you have to accept they take precedence, you'd never try to create a class called std::string would you?

Patrick
std::string is a class conveniently placed in a namespace, which application code doesn't need or want to change, and which doesn't affect anything outside the namespace. "#define UpdateResource UpdateResourceW" is a nasty hack which ... spits ... all over application code. It's perfectly reasonable for the implementation to reserve the "std" namespace (as stated in the C++ standard). It's plain rude to reserve the symbol "UpdateResource" in all uses.
Steve Jessop
@onebyone: I agree completely however if you are going to use windows libraries you have to accept that they take precedence no matter how badly written they may be.
Patrick
Yep, if the function is for Windows only then I agree with your answer, just change the name. The problem really bites when you're trying to write portable libraries. Then renaming the function is not a good option, just because Windows clients get a crazy macro along with their Windows environment that stops them calling your perfectly good function. In that situation you want a workaround to use on Windows only, and that's why I think the situation isn't really comparable to std::string.
Steve Jessop
Hadn't thought of it that way and you are absolutely right.
Patrick
A: 

One way is to document that if Winbase.h is included, it must be included before this header. Normally that would be a horrible requirement, but with Windows headers, it's pretty much a given that you're in for a world of pain unless you include them first (normally in a precompiled header, as @sharptooth says).

That done, put this in your header:

#ifdef UpdateResource
#pragma push_macro("UpdateResource")
#undef UpdateResource
#endif

Anyone simultaneously needing the original definition of UpdateResource and your class just needs to put

#pragma pop_macro("UpdateResource")
James Hopkin
A: 

Namespace is the way to go.

as Glen pointed out macros ignore namespaces
Patrick