|
The following code
CString strTest = t1 + t2;
translates to
CString strTest = CString(t1 + t2);
because you have defined the typecast to be an operator.
So here it is unable to do t1 + t2
So what you really need here is an overloaded operator + instead of operator CString
Try this -
operator CString() const {return m_str;}
CString operator + (const TestString& t2) { return m_str + t2.m_str; }
«_Superman_»
I love work. It gives me something to do between weekends.
|
|
|
|
|
but, t1 and t2 can be convert to CString in advance, then call operator+ to concatenate them. and, how to explain it can work in vc6.0
|
|
|
|
|
When you give t1 + t2 the compiler doesn't know that it needs to convert it to CString .
What if you had another operator CMyString in your class.
What if you give t1 + t2 + t3 + t4 + t5 .
Does it work in VC++ 6.0?
«_Superman_»
I love work. It gives me something to do between weekends.
|
|
|
|
|
no operator like "CMyString". t1+t2+t3+t4+t5 does work in VC6.0, even t1 + "test" + t2 also can work. the only difference I know so far is that, CString in VC7 and later version is actually CStringT<...>. but in VC6, it's just CString without template. So, i guess the template is the root cause of such error.
|
|
|
|
|
This case is covered by section 14.6.5 of the C++ Standard. The CString operator+ is defined as a class-scope friend function of the underlying template class, CStringT . The rules of C++ mean that when compiling t1 + t2 , those friend functions of CStringT are invisible.
hawkgao0129 wrote: the following code is really compilable in VC++6.0
Which was really, really non-compliant with the standard...Them's the breaks!
The easiest solution is to add a suitable operator to your TestString class:
class TestString {
CString m_str;
public:
TestString(TCHAR* str):m_str(str) {}
operator CString() const {return m_str;}
<big>friend CString operator+(const TestString& t1, const TestString& t2) { return (CString)t1 + t2; }</big>
};
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
|
|
|
|
|
|
I actually meant the ISO Standard, published in 1998 (which I bought for $18 in 2001 - a good buy, IMO) - that's the latest language level standard published. However, that working draft has (as far as I can tell) the same text for the section I referenced as the 1998 standard.
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
|
|
|
|
|
|
Yes
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
|
|
|
|
|
in addition, i also known why "CString strTest = t1 + (CString)t2;" can work fine in VC9. because of "Argument-Dependent Name (Koenig) Lookup", which was implemented after vs.net2003, operator+ can be looked up in CStringT. The real reason for that problem is, "Argument-Dependent Name Lookup" and "Conversion Functions" cannot work together. "Argument-Dependent Name Lookup" doesn't do type conversion for it's argument.
|
|
|
|
|
hawkgao0129 wrote: The real reason for that problem is, "Argument-Dependent Name Lookup" and "Conversion Functions" cannot work together
Not for *all* the function parameters no, because type conversions are taken into account only after the set of candidate overloads has been determined (which is when ADL (argument-dependent lookup) comes into play). However, if you look at the example you've shown, CString strTest = t1 + (CString)t2; , the operator is found through ADL. For it to be used, however, the first parameter has to be convertible from TestString to CString, which is performed using your user-defined conversion operator.
As I would imagine you're realising, the C++ name lookup rules are very complex
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
|
|
|
|
|
understood.
The whole story is: for t1+t2 case, at the very first, there is no operator+ with TestString argument list exists. Then, ADL is launched. ADL finds operator+ in CStringT may be the right choice. But, these are friend functions defined in CStringT, TestString doesn't have permission to access them.
for t1+(CString)t2 case, t2 has been converted to CStringT. As the rule of ADL, friend function operator+ can be accessed by CStringT itself. So, t1+(CString)t2 is legal.
Am I right?
|
|
|
|
|
hawkgao0129 wrote: ADL finds operator+ in CStringT
No. The CStringT operator+ is not visible (so is not found). ADL doesn't come into play because you've declared TestString within the global namespace.
In addition, (I may have mis-stated this earlier) ADL won't find the operator+ in CStringT even if you did put TestString in the ATL namespace because it's a friend function defined in class scope, so is only visible to parameters of type CStringT.
As I said - C++ name lookup rules are very complex - so I apologise for making some slight mistakes in explanation (but remain unsurprised that I did so ).
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
|
|
|
|
|
Do you notice the error message in my first post. Compiler seems have found the operator+ in CStringT and CStringT's parent class.
1>c:\build\test\test\test.cpp(19) : error C3767: '+': candidate function(s) not accessible
1> could be the friend function at 'c:\program files\microsoft visual studio 9.0\vc\atlmfc\include\atlsimpstr.h(653)' : '+' [may be found via argument-dependent lookup]
...
And, Is my statement about "t1+(CString)t2" right?
modified on Wednesday, July 22, 2009 5:31 AM
|
|
|
|
|
I did notice that. Which is why (when I compiled your code), I tried sticking TestString in the ATL namespace (same as CStringT). And it didn't work - but I'm starting to think I got the wrong namespace - I've tried some more experiments that confuse things a little, and seem to indicate that there is at least one bug associated with name lookup in VC.
I wrote this code:
namespace Test
{
class A
{
public:
friend void TestFn(const A&) { }
};
class B
{
public:
operator A(){ return A(); }
};
}
class C
{
public:
operator Test::A(){ return Test::A(); }
};
using namespace Test;
void X()
{
A a;
B b;
C c;
TestFn(a);
TestFn((A)b);
TestFn((A)c);
TestFn(b);
TestFn(c);
}
You can see what I *thought* should happen in the comments. However, VC++ compiles the second last line (TestFn(b); ) instead of raising an error. gcc, on the other hand, conforms exactly to my reading of the standard, compiling the first three function calls but not the last two.
Oh - and the error that VC++ raises for the line TestFn(c); ? It's this:
error C3767: 'TestFn': candidate function(s) not accessible
could be the friend function at 'd.cpp(6)' : 'TestFn' [may be found via argument-dependent lookup]
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
|
|
|
|
|
I'm sending (PostMessage ) from a worker-thread to the main thread a custom message to do some refresh.
What happens is that it looks that a big amount of messages are in some cases accumulated into the list of message.
I don't want to reduce the rate of messages sent.
Is there a simple way when posting [worker-thread] a new message to remove older (obsolete) message (of course the same message type) and leave there only the new one? Or it is possible to tell to the main thread to avoid to process a message if there is in the list the some copy less old than the current one?
Russell
|
|
|
|
|
You can use SendMessageCallback[^] instead of PostMessage .
This API return immediately just like PostMessage .
When the message handler is finished with processing the message the callback function passed in as parameter to SendMessageCallback is called. This way you can keep track of whether a specific message handler has finished processing the message.
«_Superman_»
I love work. It gives me something to do between weekends.
|
|
|
|
|
I want to disable F12 i.e Save As in word throught automation vc++.
Iam using dsoframectrl,inside this Iam opening word document.Ane need to disable F12.
Please suggest me do accomplish this.
|
|
|
|
|
Hello all,
I m having three different Link-list say apple,mango,banana.
I need to implement common delete function for all the link-list.
Is it possible?
Thank You...
|
|
|
|
|
yes.
You need to google first, if you have "It's urgent please" mentioned in your question.
_AnShUmAn_
|
|
|
|
|
ok, how we can do this? can u explain please?
|
|
|
|
|
One way is to do it using the friend function
You need to google first, if you have "It's urgent please" mentioned in your question.
_AnShUmAn_
|
|
|
|
|
make the link list a template class say.
class listList<t>
{
}
T can be apple, mango, banana
and override the delete function of the class of list
|
|
|
|
|
Yes, so long as your three linked lists all provide the same interface (and while we're here - if you're not using the standard libraries list template, then why not?).
You can use a template function, like so:
template<class ListType>
void DeleteTheList(ListType& list)
{
}
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
|
|
|
|
|
hi... i have developed MFC (exe) application.but it would run on only those systems where visual studio has installed....how can i use this application on which ever system i want....like the other commercial softwares.... plzzzzzzzzzz help me in that!!!!!
thanks.
|
|
|
|