What is <<= operator in C++ - c++

I found following code in a legacy system.As it seems to be a "assign and left shift" but I see this code is copying a string to ws but I couldn't understand how ? I wonder if simple assignment would have been enough to copy one string to another then why someone would code like this ?
vector<string> unique_dirs;
......
......
......
std::wstring ws;
ws <<= unique_dirs[i];
Edit - I looked at the class implementation (c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\xstring) . There is no such operator "<<=" overloaded in the class.

There is no such standard overload operator the left operand of which is std::wstring and the right operand is std::string. You should investigate the code where this operator was encountered that to find its definition.

By default :
ws <<= unique_dirs[i]
is the same as :
ws = ws << unique_dirs[i]
It is simply the Bitwise left shift assignment.
But in this case, it should be overloaded to work with strings.

Despite my comment that investigating the code would be easier than people guessing what is happening, here is my guess at a possible implementation, as you were wondering how it could be done - this could appear anywhere in the code, pretty much, providing it can be seen where it is being called, as it's not modifying any of the standard library classes:
std::wstring& operator<<=(std::wstring& out, const std::string& in) {
out += std::wstring(in.begin(), in.end());
return out;
}
My guess here is that as a string is being passed to a wstring, the operator is performing some kind of "widening" (a poor-mans conversion from char to wchar, disregarding encoding).
Why would you want this rather than using a straight assignment? Well, aside from ws = unique_dirs[i]; being a compilation error, it could provide you with a method of concatenating strings:
std::string hello("hello ");
std::string goodbye("goodbye");
std::wstring ws;
ws <<= hello;
ws <<= goodbye;
// ws now is L"hello goodbye"
As an aside, the above does not modify the standard library - it is not extending the std::basic_string class, it's simply providing an operator that takes two classes as parameters. So I'm not sure how it comes under "legality" with regards its usage. It is fairly horrific, however, and its usage is morally reprehensible.

Unless the <<= is overloaded, It is the bitwise left shift operator.
ws <<= unique_dirs[i]
means
ws = ws << unique_dirs[i]
Although I am doubtful about the logic behind how the code is using some string element in the vector for this purpose.

Related

"<< / >>" Operators in C++

So since I can't find anything on Google due to them somehow not accepting the search term ">>", I decided to ask here.
First of, no I do not mean the bitwise shift operator. This is different. I've seen it occur in some code and it would make no sense if it was a shift operator.
cout << a; would be an example. I know it prints out a, but what is the definition of "<<"?
Or in my case, I have a code similar to this:
for(int index=0;index<n;index++)
inputFile >> StringArray[index];
What does it mean?
The bitshift operator is frequently overloaded to mean reading values from and writing to streams.
Edit: In slightly more detail, C++ lets you overload, or change the meaning of, almost any operator. The << and >> operators were chosen to be overloaded for writing/reading to a source or sink of data because they visually look like arrows or conduits. There is zero commonality with shifting bits except as to what operator is used.
They are bitwise shifting overloaded operators, usually called 'stream operators'
I don't know it in detail but as you said,
cout<<a;
outputs the value of a, that is it puts the value of a into the output stream which get displayed on the screen.
And in the case of
inputfile>>variable;
You are reading the data from the file into the variable.
It's about writing to or reading from streams.
Check this out for a practical example: http://www.cplusplus.com/doc/tutorial/files and http://www.umich.edu/~eecs381/handouts/filestreams.pdf‎.
These are called bitwise operators, as you said.
However, in C++ you can overload these operators (in fact any operator) to do what you want them to. This is what is happening here. The << and >> are overloaded in the ostream and istream objects, to print to and read from a stream, respectively.
In fact you could overload any operator to do whatever you want on an object. An example can be found here.
Cheers.
PS: The concept around these operators is easily visualized. When you write:
cout << "Hello world";
with a little bit of imagination, you could say that you "put" the string on the right to the cout stream on the left (thus the left directed "arrows"). Same, when you write:
std::string str;
cin >> str;
you could imagine that you extract a string from the cin stream on the left and "put" it on the str variable on the right (thus the right directed "arrows").

what does the left shift operator do in converting from integer to string in c++

Suppose you want to convert an integer into string this is the method in c++
int c1=999;
stringstream ss;
ss<<c1;
string str=ss.str();
How is it converting into string in c++? What does the stringstream contains and in the 3rd line of the above program
in that statement i.e I mean what does the left shift operator (as we know that the symbol '<<' is used for left shifting) is doing here to converting into string
To convert an int to string (very basically), you have to go through all digits, translate it to a regular char, and put it in the string :
int toConvert = 999;
string res = "";
while (toConvert)
{
int lastDigit = toConvert % 10; //retrieve last digit
char c = lastDigit + '0'; //translate it to the char corresponding
string reverse(c); //We have to add it in front of the string, or otherwise
reverse.append (res); // the digits will be reversed.
res = reverse;
toConvert /= 10;
}
This is a very basic way to translate int to string, and I'm sure it's done way better in the operator "<<", but you get the idea.
The left shift here is overload by append function, think of it as
ss.append(c1) where the append can have multiple functions
append(int i)
append(string s)
append(byte b)
etc
each function do the actual translation to the right string and appending it...
There's no left shift operator in your code. In C, << was left shift. In C++, it's the stream insertion operator (with support for left shift as well, for reasons of C compatibility).
You are allowed to overload various operators in C++, including bitwise left shift <<. Conceptually you can override it do to anything; the only restriction being that the number of operands can't be changed.
The streaming classes in the C++ IO stream libraries exploit this. It's syntatically cute to use << to write the argument to the stream in some way, as clearly, bitwise shifting a stream has no meaning so the operator may as well be used to do something else. That is what ss<<c1; is doing. It's not doing anything like a bitwise shift.
There is a school of thought that says that operator overloading is confusing (perhaps this is why this question has been asked). That's why operator overloading didn't make it into Java.
<< in this situation isn't exactly the Left Shift Operator.
Its a Stream Operator.
It appends (inserts) the characters in to your string stream.

C++ Need Help Overloading += for a MyString Class

I'm working on writing my own string class and am having trouble with overloading the += operator for a MyString being +='d to a char. I figured this would work but with no luck. Here's the implementation I tried. Any assistance on getting it to work correctly will be much appreciated.
MyString& MyString::operator +=(char c)
{
char derp[1] = {c};
strcat(value, derp);
return *this;
}
This is not going to work for several reasons:
derp is not a null-terminated array, which it has to be if you pass it as a parameter to strcat
There is no check that the buffer that value represents can actually hold more data; neither is there a facility to make sure that the buffer is always null-terminated (which again it needs to be because you are passing it to strcat)
Even if you correct the above, your string class will never be able to include the character \0 as part of a string value because that will be mistaken for a null terminator; in technical terms, your string class would not be "binary safe"; to fix this you need to drop strcat and similar functions entirely and switch to memcpy and friends
Apart from the above, overloading operator += like this allows for code such as
MyString str("foo");
foo += 80; // this compiles, but should it?
Finally, the str*** family of functions is going to get needlessly slower as your strings are getting larger (because they have to scan the string from the beginning each time in order to determine where it ends). Keeping your own length variable and switching to mem*** is going to fix this issue as well.
The use of strcat is incorrect as it requires a null terminated source string and is being provided with a buffer with no null terminator.
value will only be capable of holding a finite number of characters, and there is no attempt to increase the size of value.
Assuming value is large enough and you retain the length of the string inside your instance, I'd say:
value[size] = c;
value[size+1] = '\0';

What's the reasoning behind putting constants in 'if' statements first?

I was looking at some example C++ code for a hardware interface I'm working with and noticed a lot of statements along the following lines:
if ( NULL == pMsg ) return rv;
I'm sure I've heard people say that putting the constant first is a good idea, but why is that? Is it just so that if you have a large statement you can quickly see what you're comparing against or is there more to it?
So that you don't mix comparison (==) with assignment (=).
As you know, you can't assign to a constant. If you try, the compiler will give you an error.
Basically, it's one of defensive programming techniques. To protect yourself from yourself.
To stop you from writing:
if ( pMsg = NULL ) return rv;
by mistake. A good compiler will warn you about this however, so most people don't use the "constant first" way, as they find it difficult to read.
It stops the single = assignment bug.
Eg,
if ( NULL = pMsg ) return rv;
won't compile, where as
if ( pMsg = NULL) return rv;
will compile and give you headaches
To clarify what I wrote in some of the comments, here is a reason not to do this in C++ code.
Someone writes, say, a string class and decides to add a cast operator to const char*:
class BadString
{
public:
BadString(const char* s) : mStr(s) { }
operator const char*() const { return mStr.c_str(); }
bool operator==(const BadString& s) { return mStr == s.mStr; }
// Other stuff...
private:
std::string mStr;
};
Now someone blindly applies the constant == variable "defensive" programming pattern:
BadString s("foo");
if ("foo" == s) // Oops. This compares pointers and is never true.
{
// ...
}
This is, IMO, a more insidious problem than accidental assignment because you can't tell from the call site that anything is obviously wrong.
Of course, the real lessons are:
Don't write your own string classes.
Avoid implicit cast operators, especially when doing (1).
But sometimes you're dealing with third-party APIs you can't control. For example, the _bstr_t string class common in Windows COM programming suffers from this flaw.
When the constant is first, the compiler will warn you if you accidentally write = rather than == since it's illegal to assign a value to a constant.
Compilers outputting warnings is good, but some of us in the real world can't afford to treat warnings as errors. Reversing the order of variable and constant means this simple slip always shows up as an error and prevents compilation. You get used to this pattern very quickly, and the bug it protects against is a subtle one, which is often difficult to find once introduced.
They said, "to prevent mixing of assignment and comparison".
In reality I think it is nonsense: if you are so disciplined that you don't forget to put constant at the left side, you definitely won't mix up '=' with '==', would you? ;)
I forget the article, but the quote went something like:
Evidently it's easier remembering to put the constant first, than it is remembering to use ==" ;))

Why doesn't C++ reimplement C standard functions with C++ elements/style?

For a specific example, consider atoi(const std::string &). This is very frustrating, since we as programmers would need to use it so much.
More general question is why does not C++ standard library reimplement the standard C libraries with C++ string,C++ vector or other C++ standard element rather than to preserve the old C standard libraries and force us use the old char * interface?
Its time consuming and the code to translate data types between these two interfaces is not easy to be elegant.
Is it for compatible reason,considering there was much more legacy C code than these days and preserving these C standard interfaces would make translation from C code to C++ much easier?
In addition,I have heard many other libraries available for C++ make a lot of enhancement and extensions to STL.So does there libraries support these functions?
PS: Considering much more answers to the first specific question, I edit a lot to clarify the question to outline the questions that I am much more curious to ask.
Another more general question is why do not STL reimplementate all the standard C libraries
Because the old C libraries do the trick. The C++ standard library only re-implements existing functionality if they can do it significantly better than the old version. And for some parts of the C library, the benefit of writing new C++-implementations just isn't big enough to justify the extra standardization work.
As for atoi and the like, there are new versions of these in the C++ standard library, in the std::stringstream class.
To convert from a type T to a type U:
T in;
U out;
std::stringstream sstr(in);
sstr >> out;
As with the rest of the IOStream library, it's not perfect, it's pretty verbose, it's impressively slow and so on, but it works, and usually it is good enough. It can handle integers of all sizes, floating-point values, C and C++ strings and any other object which defines the operator <<.
EDIT:In addition,I have heard many other libraries avaliable for C++ make a lot of enhancement and extensions to STL.So does there libraries support these functions?
Boost has a boost::lexical_cast which wraps std::stringstream. With that function, you can write the above as:
U out = boost::lexical_cast<U>(in);
Even in C, using atoi isn't a good thing to do for converting user input. It doesn't provide error checking at all. Providing a C++ version of it wouldn't be all that useful - considering that it wouldn't throw and do anything, you can just pass .c_str() to it and use it.
Instead you should use strtol in C code, which does do error checking. In C++03, you can use stringstreams to do the same, but their use is error-prone: What exactly do you need to check for? .bad(), .fail(), or .eof()? How do you eat up remaining whitespace? What about formatting flags? Such questions shouldn't bother the average user, that just want to convert his string. boost::lexical_cast does do a good job, but incidentally, C++0x adds utility functions to facilitate fast and safe conversions, through C++ wrappers that can throw if conversion failed:
int stoi(const string& str, size_t *idx = 0, int base = 10);
long stol(const string& str, size_t *idx = 0, int base = 10);
unsigned long stoul(const string& str, size_t *idx = 0, int base = 10);
long long stoll(const string& str, size_t *idx = 0, int base = 10);
unsigned long long stoull(const string& str, size_t *idx = 0, int base = 10);
Effects: the first two functions call strtol(str.c_str(), ptr, base), and the last three functions
call strtoul(str.c_str(), ptr, base), strtoll(str.c_str(), ptr, base), and strtoull(str.c_str(), ptr, base), respectively. Each function returns the converted result, if any. The argument ptr designates a pointer to an object internal to the function that is used to determine what to store at *idx. If the function does not throw an exception and idx != 0, the function stores in *idx the index of the first unconverted element of str.
Returns: the converted result.
Throws: invalid_argument if strtol, strtoul, strtoll, or strtoull reports that no conversion could be performed. Throws out_of_range if the converted value is outside the range of representable values for the return type.
There's no good way to know if atoi fails. It always returns an integer. Is that integer a valid conversion? Or is the 0 or -1 or whatever indicating an error? Yes it could throw an exception, but that would change the original contract, and you'd have to update all your code to catch the exception (which is what the OP is complaining about).
If translation is too time consuming, write your own atoi:
int atoi(const std::string& str)
{
std::istringstream stream(str);
int ret = 0;
stream >> ret;
return ret;
}
I see that solutions are offered that use std::stringstream or std::istringstream.
This might be perfectly OK for single threaded applications but if an application has lots of threads and often calls atoi(const std::string& str) implemented in this way that will result in performance degradation.
Read this discussion for example: http://gcc.gnu.org/ml/gcc-bugs/2009-05/msg00798.html.
And see a backtrace of the constructor of std::istringstream:
#0 0x200000007eb77810:0 in pthread_mutex_unlock+0x10 ()
from /usr/lib/hpux32/libc.so.1
#1 0x200000007ef22590 in std::locale::locale (this=0x7fffeee8)
at gthr-default.h:704
#2 0x200000007ef29500 in std::ios_base::ios_base (this=<not available>)
at /tmp/gcc-4.3.1.tar.gz/gcc-4.3.1/libstdc++-v3/src/ios.cc:83
#3 0x200000007ee8cd70 in std::basic_istringstream<char,std::char_traits<char>,std::allocator<char> >::basic_istringstream (this=0x7fffee4c,
__str=#0x7fffee44, __mode=_S_in) at basic_ios.h:456
#4 0x4000f70:0 in main () at main.cpp:7
So every time you enter atoi() and create a local varibale of type std::stringstream you will lock a global mutex and in a multithreaded application it is likely to result in waiting on this mutex.
So, it's better in a multithreaded application not to use std::stringstream. For example simply call atoi(const char*):
inline int atoi(const std::string& str)
{
return atoi(str.c_str());
}
For your example, you've got two options:
std::string mystring("4");
int myint = atoi(mystring.c_str());
Or something like:
std::string mystring("4");
std::istringstream buffer(mystring);
int myint = 0;
buffer >> myint;
The second option gives you better error management than the first.
You can write a more generic string to number convert as such:
template <class T>
T strToNum(const std::string &inputString,
std::ios_base &(*f)(std::ios_base&) = std::dec)
{
T t;
std::istringstream stringStream(inputString);
if ((stringStream >> f >> t).fail())
{
throw runtime_error("Invalid conversion");
}
return t;
}
// Example usage
unsigned long ulongValue = strToNum<unsigned long>(strValue);
int intValue = strToNum<int>(strValue);
int intValueFromHex = strToNum<int>(strHexValue,std::hex);
unsigned long ulOctValue = strToNum<unsigned long>(strOctVal, std::oct);
For conversions I find simplest to use boost's lexical_cast (except it might be too rigorously checking the validity of the conversions of string to other types).
It surely isn't very fast (it just uses std::stringstream under the hood, but significantly more convenient), but performance is often not needed where you convert values (e.g to create error output messages and such). (If you do lots of these conversions and need extreme performance, chances are you are doing something wrong and shouldn't be performing any conversions at all.)
Because the old C libraries still work with standard C++ types, with a very little bit of adaptation. You can easily change a const char * to a std::string with a constructor, and change back with std::string::c_str(). In your example, with std::string s, just call atoi(s.c_str()) and you're fine. As long as you can switch back and forth easily there's no need to add new functionality.
I'm not coming up with C functions that work on arrays and not container classes, except for things like qsort() and bsearch(), and the STL has better ways to do such things. If you had specific examples, I could consider them.
C++ does need to support the old C libraries for compatibility purposes, but the tendency is to provide new techniques where warranted, and provide interfaces for the old functions when there isn't much of an improvement. For example, the Boost lexical_cast is an improvement over such functions as atoi() and strtol(), much as the standard C++ string is an improvement over the C way of doing things. (Sometimes this is subjective. While C++ streams have considerable advantages over the C I/O functions, there's times when I'd rather drop back to the C way of doing things. Some parts of the C++ standard library are excellent, and some parts, well, aren't.)
There are all sorts of ways to parse a number from a string, atoi can easily be used with a std::string via atoi(std.c_str()) if you really want, but atoi has a bad interface because there is no sure way to determine if an error occurred during parsing.
Here's one slightly more modern C++ way to get an int from a std::string:
std::istringstream tmpstream(str);
if (tmpstream >> intvar)
{
// ... success! ...
}
The tongue in cheek answer is: Because STL is a half-hearted attempt to show how powerful C++ templates could be. Before they got to each corner of the problem space, time was up.
There are two reasons: Creating an API takes time and effort. Create a good API takes a lot of time and a huge effort. Creating a great API takes an insane amount of time and an incredible effort. When the STL was created, OO was still pretty new to the C++ people. They didn't have the ideas how to make fluent and simple API. Today, we think iterators are so 1990 but at the time, people thought "Bloody hell, why would I need that? for (int i=0; i<...) has been good enough for three decades!"
So STL didn't became the great, fluent API. This isn't all C++ fault because you can make good APIs with C++. But it was the first attempt to do that and it shows. Before the API could mature, it was turned into a standard and all the ugly shortcomings were set into stone. And on top of this, there was all this legacy code and all the libraries which already could do everything, so the pressure wasn't really there.
To solve your misery, give up on STL and have a look at the successors: Try boost and maybe Qt. Yeah, Qt is a UI library but it also has a pretty good standard library.
Since C++11, you can use std::stoi. It is like atoi but for std::string.