Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: C++
Using delegates:
I own class creates an instance of the library class on the heap and only stores its pointer.
 
JString& JString::format( const TCHAR* formatString, ... )
{
    m_Imp->format(formatString,...);//the compiler warning this!
    return *this;
}
 
m_imp is the library class pointer that delegate.
JString is the wrapper class.
 
How can i solve the compiler warning?
Posted 16-Apr-13 18:20pm
Comments
Sergey Alexandrovich Kryukov at 16-Apr-13 23:39pm
   
On unmanaged heap, I guess? Do you mean CLI delegates? I don't know what's a C++/CLI "delegate".
I know only C++/CLI delegates, heard of C++/CX delegates... Will you clarify it?
—SA
jiazhiqiang at 16-Apr-13 23:49pm
   
m_Imp is the pointer member of JString.it will Alloc on Heap in the constuctor of JString.
Now It just How to pass the outer JString format() "..." to inter m_Imp 's format().
Sergey Alexandrovich Kryukov at 17-Apr-13 0:09am
   
Sorry, I have no idea what JString is (and I hope this is totally irrelevant). You need to answer two of my question:
1) managed vs. unmanaged heap (C++, C++/CLI or mixed-mode); do you understand the question?
2) what is the delegate, in your case? .NET (CLI) delegate, or something else?
—SA
jiazhiqiang at 17-Apr-13 0:21am
   
I'm really not understand what's you mean.
I I just Want to ask "How to pass the outer JString format() "..." argument to inter m_Imp 's format() which also need the "..." argument ?"
thanks!
Sergey Alexandrovich Kryukov at 17-Apr-13 0:31am
   
I do understand about '...'.
Do you use .NET (CLI) or not? If not, please explain what do you mean by "delegate".
—SA
Stefan_Lang at 17-Apr-13 4:33am
   
I think this is just a C++ implementation of the delgation design pattern. See http://en.wikipedia.org/wiki/Delegation_pattern. This has nothing to do with MS delegates. It's a bit unfortunate MS used this term as a keyword for MS-specific stuff - this is the source of confusion here.
Sergey Alexandrovich Kryukov at 17-Apr-13 11:08am
   
May be, but I would need to here about that from OP. I was trying to lead OP to this clarification, so far, not successfully. Without that, I don't see a sense it answering.
—SA
Stefan_Lang at 17-Apr-13 11:15am
   
He may not even be aware of MS delegates or the need for clarification. *I* wasn't aware of them either until a couple of hours ago. MS really would do everyone a favor if they stopped hijacking known terminology for labeling their own, unrelated concepts!
Sergey Alexandrovich Kryukov at 17-Apr-13 12:24pm
   
I would modestly suggest that everyone used only the terms she or he understand. And you are quite right about MS terminology perversions, which happens occasionally (not always and not often, to be fair).
 
Do you know what irritates me the most? In Microsoft applications and APIs, UTF-16LE is called "Unicode". So many developers have been totally confused; sometimes, into complete misunderstanding of what Unicode is!
 
—SA
Sergey Alexandrovich Kryukov at 17-Apr-13 11:17am
   
I added my Solution 2, to complement Solution 1.
I also added and credited you for the link you provided, thank you very much.
I added some judgement on using "free parameters" with or without delegation, please see.
—SA
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 2

In addition to Solution 1:
 
Here is how '...' arguments are used (please see also my comments to Solution 1):
http://www.cplusplus.com/reference/cstdarg/va_arg/[^].
 
Using of such arguments is usually highly discourage. First of all, C calling convention is required, which is C/C++ only and not used in OP API, by performance, safety and other reasons. (Do I have to explain how why and how it works? A hint: a caller pops the stack.)
 
In principle, such arguments could be used in delegate pattern (please see: http://en.wikipedia.org/wiki/Delegation_pattern[^]; credited to Stephan Lang, please see his comments to the question) as well, but I don't think it is ever done, and I would not recommend it. There is an alternative method good for any calling conventions: an additional parameters are put in one array argument, or two: array length and array.
 
—SA
  Permalink  
v3
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

I assume the term "delegate" in the title of your question is not related to what is generally understood as a "delegate". You just want to forward the function call via a pointer to a function.
 
The compiler is stumbling over the "..." in the argument list. In fact, there is no way of simply forwarding a variable argument list from one function to the next. The usual construct in C++ to deal with that problem is the following:
 
JString& JString::format( const TCHAR* formatString, ... )
{
    va_list args;
    va_start (args, formatString);
 
    m_Imp->format(formatString, args); // the function called here must be aware
                                       // that args is of type va_list and can iterate
                                       // through the remaining arguments via the args pointer

    return *this;
}
 
That is how printf and the like are implemented in the C++ runtime library. This only works if the function you call knows that the second argument is in fact a pointer to the variable argument list.
  Permalink  
Comments
Stefan_Lang at 17-Apr-13 4:37am
   
Great response, +5. I spend a couple of minutes trying to remember this va_* stuff but couldn't come up with a useful enough keyword to power a search. I should have immediately checked out your response ;)
nv3 at 17-Apr-13 5:02am
   
Thanks, Stefan!
jsolutions_uk at 17-Apr-13 7:05am
   
5 from me, bring on variadic templates :)
nv3 at 17-Apr-13 7:35am
   
Thanks for comment and your vote. If OP were using C++11 that would in fact be an option. However, variadic function templates don't make life easier in that case. So I'd stay away from recommending that approach in this particular case.
jsolutions_uk at 17-Apr-13 7:41am
   
Fair comment :)
Sergey Alexandrovich Kryukov at 17-Apr-13 11:15am
   
I voted 4. There are many good points here, including "not a delegate" explanation (important, a delegate instance carries "this" in it, a pointer to the instance, in case of non-static (instance) method). You correctly pass '...' transparently to other function declaring '...', but it does not explain the nature of '...'. In fact, the parameters are put on stack according to the current stack layout alignment model, and the method should extract those arguments from stack.
—SA
nv3 at 17-Apr-13 11:34am
   
"and the method should extract those arguments from stack"
which is impossible in C++, because neither type nor number of arguments are know. So I think the better solution is to do it like the C++ runtime library does: pass the argument pointer and leave the extraction of the arguments to the function that interprets the format string.
 
Thanks for your amendments in solution 2 and for your vote, Sergey.
Sergey Alexandrovich Kryukov at 17-Apr-13 12:18pm
   
You mean it's impossible to implement prinft in pure C++? It is possible, but not a good idea. Please see my first link. You need to typecast each argument...
—SA
nv3 at 17-Apr-13 14:32pm
   
No, that's not what I meant. It is impossible to forward those optional parameters that come into JString::format to the function pointed to by m_Imp in a strict one-to-one manner. That's what I understand as OPs question. And of course it's possible to implement printf in C++. Most C++ runtime libraries do it that way.
Sergey Alexandrovich Kryukov at 17-Apr-13 15:02pm
   
Got it, thank you.
—SA
Sergey Alexandrovich Kryukov at 17-Apr-13 11:16am
   
I added my Solution 2, to complement it.
—SA

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



Advertise | Privacy | Mobile
Web02 | 2.8.1411023.1 | Last Updated 17 Apr 2013
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100