Does boost::variant work with std::string? - c++

I've written a simple program in C++ with use of boost::variant. Program's code is presented below.
#include <string>
#include <iostream>
#include <boost/variant.hpp>
int main (int argc, char** argv)
{
boost::variant<int, std::wstring> v;
v = 3;
std::cout << v << std::endl;
return 0;
}
But when I try to compile this with command
g++ main.cpp -o main -lboost_system
i get
/usr/include/boost/variant/detail/variant_io.hpp:64: error: no match for ‘operator<<’ in ‘((const boost::detail::variant::printer<std::basic_ostream<char, std::char_traits<char> > >*)this)->boost::detail::variant::printer<std::basic_ostream<char, std::char_traits<char> > >::out_ << operand’
followed by a bunch of candidate functions.
What I'm missing? The funny thing is When I use std::string instead of std::wstring everything works great.
Thanks in advance.

The problem is that wstring cannot be << in cout. Try using wcout instead. This is not a problem with the variant.

Use wcout, not cout. Because you're using wstring, not string.
std::wcout << v << std::endl;
//^^^^ note
Demo : http://ideone.com/ynf15

Related

Misinterpretation of operator precedence when using ostream and ostringstream

The following code has different compile results. From the error message I'm receiving it seems there's a confusion about operators precedence () and <<. I can easily overcome this issue by using a function. However I would like to understand and to know:
a) Which compiler it's evaluating correctly the expression? MSVC2017 seems more logical to me.
b) Is there an workaround still using MACROs?
Full sample code I used.
#include <cstdlib>
#include <typeinfo>
#include <sstream>
#include <iostream>
#ifndef NDEBUG
#define EXPR_INSPECT(param_)\
( (std::ostringstream{} << "< " #param_ " [" << typeid(param_).name() << "] > : " << param_).str() )
#else
#define EXPR_INSPECT(param_)\
(param_)
#endif //NDEBUG
int main(int argc, char *argv[])
{
auto ull_x {99LLU};
std::string string_x {"Checking..."};
std::cout << EXPR_INSPECT( ull_x) << std::endl;
std::cout << EXPR_INSPECT(string_x) << std::endl;
return EXIT_SUCCESS;
}
MSVC2017 works perfectly!
G++ 8.2.0 (MSYS2/MINGW) issues the following error: 'std::basic_ostream::__ostream_type' {aka 'class std::basic_ostream'} has no member named 'str' Attempts to call str() on ostream instead of ostringstream.
EDIT:
The problem here can also be reproduced by clang using Wandbox. Here is a minimal example:
#include <sstream>
#include <iostream>
int main()
{
auto s = std::ostringstream{};
decltype(((std::ostringstream{}) << "< "))::nothing;
decltype((s << "< "))::nothing;
}
In wandbox, clang found the second type std::basic_ostream, while the first type std::basic_ostringstream. That's very strange.

c++ iterate through a vector of strings

So I recently discovered the use of map and vectors, however, I'm having trouble of trying to figure a way to loop through a vector containing strings.
Here's what I've tried:
#include <string>
#include <vector>
#include <stdio>
using namespace std;
void main() {
vector<string> data={"Hello World!","Goodbye World!"};
for (vector<string>::iterator t=data.begin(); t!=data.end(); ++t) {
cout<<*t<<endl;
}
}
and when I try to compile it, I get this error:
cd C:\Users\Jason\Desktop\EXB\Win32
wmake -f C:\Users\Jason\Desktop\EXB\Win32\exbint.mk -h -e
wpp386 ..\Source\exbint.cpp -i="C:\WATCOM/h;C:\WATCOM/h/nt" -w4 -e25 -zq -od -d2 -6r -bt=nt -fo=.obj -mf -xs -xr
..\Source\exbint.cpp(59): Error! E157: col(21) left expression must be integral
..\Source\exbint.cpp(59): Note! N717: col(21) left operand type is 'std::ostream watcall (lvalue)'
..\Source\exbint.cpp(59): Note! N718: col(21) right operand type is 'std::basic_string<char,std::char_traits<char>,std::allocator<char>> (lvalue)'
Error(E42): Last command making (C:\Users\Jason\Desktop\EXB\Win32\exbint.obj) returned a bad status
Error(E02): Make execution terminated
Execution complete
I tried the same method using map and it worked. The only difference was I changed the cout line to:
cout<<t->first<<" => "<<t->last<<endl;
Add iostream header file and change stdio to cstdio.
#include <iostream>
#include <string>
#include <vector>
#include <cstdio>
using namespace std;
int main()
{
vector<string> data={"Hello World!","Goodbye World!"};
for (vector<string>::iterator t=data.begin(); t!=data.end(); ++t)
{
cout<<*t<<endl;
}
return 0;
}
#include <iostream>
#include <vector>
#include <string>
int main()
{
std::vector<std::string> data = {"Hello World!", "Goodbye World!"};
for (std::vector<std::string>::iterator t = data.begin(); t != data.end(); t++) {
std::cout << *t << std::endl;
}
return 0;
}
Or with C++11 (or higher):
#include <iostream>
#include <vector>
#include <string>
typedef std::vector<std::string> STRVEC;
int main()
{
STRVEC data = {"Hello World!", "Goodbye World!"};
for (auto &s: data) {
std::cout << s << std::endl;
}
return 0;
}
From the Open Watcom V2 Fork-Wiki on the C++ Library Status page:
<string>
Mostly complete. Although there are no I/O operators, all other member functions and string operations are available.
A workaround (besides implementing the << operator) would be asking the string instances for the C string:
for (vector<string>::iterator t = data.begin(); t != data.end(); ++t) {
cout << t->c_str() << endl;
}
This of course only works as long as the strings don't contain zero byte values.
When I compile your code, I get:
40234801.cpp:3:17: fatal error: stdio: No such file or directory
#include <stdio>
^
You clearly have a header called "stdio" in your include path that you haven't shown us.
If you change that line to the standard #include <iostream>, then the only reported error is that you wrote void main() instead of int main(). Fix that, and it will build and run.
In passing, note also that using namespace should be avoided.
I found a solution to my own issue. Instead of using a c_str, I used std::string and switched to using the G++ compiler instead of Open Watcom
Instead of having:
char *someString="Blah blah blah";
I instead replaced it with:
string someString="Blah blah blah";
This way is much more efficient and easier.

Character by character output to simulate a typing effect

How would one would approach a situation where you want to output character per character in a C++ Program, to simulate a typing action?
Try this: (C++11)
#include <iostream>
#include <thread>
#include <chrono>
int main() {
std::string s = "Hello!";
for (const auto c : s) {
std::cout << c << std::flush;
std::this_thread::sleep_for(std::chrono::milliseconds(500));
}
std::cout << std::endl;
}
You can still use the usleep(ms) function from lib C, between each character you want to write. It works.

cout print string variable cannot pass the build

Could any one help me to figure out which the following code cannot build successfully:
#include <iostream>
int main(void){
std::string str1("sfsfasfdsdf");
std::cout << str1 << std::endl;
return 1;
}
Thanks.
You have to include std::string header:
#include <string>
EDIT: According to #ShafikYaghmour's comments, include iostream sometimes brings in string, but it may not be the case for you if you only have the posted code.

c++11 getline asking two times the input

In xcode 4.3 I have set the project to use c++11: I changed the voice c++ language dialect to c++11, and c++ standard library to "libc++ ( LLVM c++ standard library with c++11 support)".
Then I tried to compile and execute this simple code:
#include <iostream>
using namespace std;
int main (int argc, char** argv)
{
char buffer[100];
cin.getline(buffer,100);
cout << buffer << endl;
return 0;
}
The problem is that it asks two times the input.For example I type "hello" and the stream remains opened, waiting for another string.If I type another string then it prints out "hello".
If I don't use c++11 this problem doesn't occur.
Does anyone know how to solve this problem? I want to take in input maximum 100 characters without using std::string.
This is a bug in libc++. My apologies. It is fixed on Mountain Lion. You can work around it by using getline(istream&, string&) instead:
#include <iostream>
#include <string>
using namespace std;
int main (int argc, char** argv)
{
std::string buffer;
getline(cin, buffer);
cout << buffer << endl;
return 0;
}