What is the correct way to replace this:
std::ostringstream buf;
std::for_each(bd.begin(), bd.end(), buf << boost::lambda::constant(" ") << boost::lambda::_1);
With an implementation that doesn't use boost? This is what I've tried:
std::string backspace("&nbps;");
std::ostringstream buf;
std::for_each(bd.begin(), bd.end(), buf << backspace << std::placeholders::_1);
The second '<<' is underlined in red and I get the error message:
error C2679: binary '<<' : no operator found which takes a right-hand operand of type 'std::_Ph<1>' (or there is no acceptable conversion)
boost::lambda is a marvellous monstrosity that kind of backported lambdas to C++03. The equivalent to your code is:
std::ostringstream buf;
std::for_each(bd.begin(), bd.end(), [&](auto const &v) { buf << " " << v; });
... or even:
std::ostringstream buf;
for(auto const &v : bd)
buf << " " << v;
Related
I have the following functions
void Assembly::push_back(stringstream& ss){
instructions->push_back(ss.str());
}
std::ostream& pad(std::ostream& os) {
return os <<"\t"<<std::left<< std::setfill(' ') << std::setw(8);
}
where instructions is a list of strings. I want to do sth like
Assembly outfile;
stringstream ss;
outfile.push_back(ss<<pad<<"addiu"<<"$sp, $sp, -8");
but I get an error from the compiler
no known conversion for argument 1 from 'std::basic_ostream<char>' to 'std::stringstream& {aka std::basic_stringstream<char>&}'
I tried changing the definition of push_back to take std::basic_ostream<char> but it still did not compile.
Basically what I want to do is be able to push_back a string which has the alignment that pad adds. It is also essential that I am able to call Assembly::push_back in a single line (I know that
Assembly outfile;
stringstream ss;
ss<<pad<<"addiu"<<"$sp, $sp, -8";
outfile.push_back(ss);
works, but it requires two lines of code to make the proper call). I am also open to solutions which overload the operator<< for Assembly or allow me to accomplish the required behavior in a single line.
Make your pad() take and return a std::stringstream, and then also add this:
template <typename T>
std::stringstream &
operator<<(std::stringstream &ss, const T &o) {
static_cast<std::ostream &>(ss) << o; // Prevent recursion.
return ss;
}
Here is what I think the problem is. This won't work because the return value of ss << anything is always an std::ostream& which is a parent of std::stringstream and does not satisfy the argument for your push_back() function.
void push_back(const std::stringstream& ss)
{
std::cout << "push: " << ss.str() << '\n';
}
int main(int, char* argv[])
{
std::stringstream ss;
// what gets sent to the function is an std::ostream&
// which is an incompatible type.
push_back(ss << "one " << 2 << ' ' << 3.0); // fail
}
The way to fix this is to create an overload for operator<<(std::stringstream& that returns the correct type:
template<typename DataType>
std::stringstream& operator<<(std::stringstream& ss, const DataType& data)
{
static_cast<std::ostream&>(ss) << data;
return ss;
}
Now calling << on a std::stringstream will return a std::stringstream& which is acceptable as your push_back() parameter.
void push_back(const std::stringstream& ss)
{
std::cout << "push: " << ss.str() << '\n';
}
int main(int, char* argv[])
{
std::stringstream ss;
// Now the << returns the correct type (std::stringstream&)
push_back(ss << "one " << 2 << ' ' << 3.0); // good
}
There is no method std::to_u16string(...). Obviously static_cast doesn't seem the most appropiate way to make such conversion.
For the opposite conversion, from string to int, a converter may be defined using the function std::stoi(), but from int to u16string it's not working.
I tried the following:
int i = 1234;
std::u16string s;
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert;
s = convert.from_bytes(std::to_string(i));
std::cout << s.str() << " (" << s.length() << ")" << std::endl;
I also tried to do this:
typedef std::basic_stringstream<char16_t> u16ss;
u16ss ss;
ss << 1234;
std::u16string s = ss.str();
but it doesn't work.
Is there a way to carry out this conversion directly, or there must be some intermediate conversions?
You could try the following:
std::u16string to_u16string(int const &i) {
std::wstring_convert<std::codecvt_utf8_utf16<char16_t, 0x10ffff, std::little_endian>, char16_t> conv;
return conv.from_bytes(std::to_string(i));
}
Live Demo
I´m building this simple C++ program using Visual Studio 2012:
#include <stdafx.h>
#include <string>
#include <iostream>
int main()
{
std::wcout << "Hello World...";
std::string input_data;
std::string output_data("Hello. Please type your name");
std::wcout << output_data;
std::wcin >> input_data;
std::wcout << "Your name is " << input_data;
return 0;
}
I can´t compile. Getting the followig errors:
error C2678: binary '>>' : no operator found which takes a left-hand operand of type 'std::wistream' (or there is no acceptable conversion)
error C2679: binary '<<' : no operator found which takes a right-hand operand of type 'std::string' (or there is no acceptable conversion)
error C2679: binary '<<' : no operator found which takes a right-hand operand of type 'std::string' (or there is no acceptable conversion)
IntelliSense: no operator "<<" matches these operands
operand types are: std::basic_ostream<wchar_t, std::char_traits<wchar_t>> << std::string
IntelliSense: no operator "<<" matches these operands
operand types are: std::wostream << std::string
IntelliSense: no operator ">>" matches these operands
operand types are: std::wistream >> std::string
Can someone help me to fix that ?
You should try changing all std::string ocurrences for std::wstring... or all wcin/wcout for cin/cout... (in the first case, prefix the strings like L"aaa" This, for instance, works perfectly:
#include <string>
#include <iostream>
int main()
{
std::wcout << L"Hello World...";
std::wstring input_data;
std::wstring output_data(L"Hello. Please type your name");
std::wcout << output_data;
std::wcin >> input_data;
std::wcout << L"Your name is " << input_data;
return 0;
}
Alternatively, you could switch everything to narrow strings:
#include <string>
#include <iostream>
int main()
{
std::cout << "Hello World...";
std::string input_data;
std::string output_data("Hello. Please type your name");
std::cout << output_data;
std::cin >> input_data;
std::cout << "Your name is " << input_data;
return 0;
}
I'm still fairly rusty at c++ and I'm having trouble understanding my issue. The error message that I am receiving is "No operator '<<' matches these operands" The code I have:
for(int i = 0; i < ruleList.size(); i++)
{
cout << ruleList[i].lhs << endl;
cout << ruleList[i].rhs << endl; // Problem printing this
}
struct Rules
{
string lhs;
vector<string> rhs;
}rule;
vector<Rules> ruleList;
Would this be the appropriate way to do this? I did the lhs the same way and it works fine.
rule.rhs.push_back(token);
ruleList.push_back(rule);
There is no operator<< defined for standard containers. You will need to write a print function, something along the lines of:
void print(std::ostream& out, std::vector<std::string> const & data) {
std::copy(data.begin(), data.end(),
std::ostream_iterator<std::string>(out, " "));
}
And then use it as:
print(std::cout, ruleList[i].rhs);
std::vector does not define an operator <<. You can use a std::ostream_iterator to format a list:
std::copy( ruleList[i].rhs.begin(), ruleList[i].rhs.end(),
std::ostream_iterator< std::string >( std::cout, ", " ) );
This is a bit imperfect in that ", " is printed after the final element, but that can be worked around.
You need to write your own << operator for struct rules. It should look something like this in C++11:
struct rules {
string lhs;
std::vector<std::string> rhs;
// apparently it's a good idea to keep this out of std:: namespace
inline static std::ostream & operator << (std::ostream & out, const rules & r) {
out << r.lhs << std::endl;
//for (int i = 0; i < v.length(); i++)
for (auto & s : r.rhs) {
out << s;
}
out << std::endl;
return out;
}
}
MSDN has a write up here: http://msdn.microsoft.com/en-us/library/1z2f6c2k.aspx
I was trying to think of a clever way to concatenate various things into a single string argument for a function without having to use an ostringstream explicitly. I thought of:
#define OSS(...) \
dynamic_cast<std::ostringstream const&>(std::ostringstream() << __VA_ARGS__).str()
However, given:
void f( string const &s ) {
cout << s << endl;
}
int main() {
char const *const s = "hello";
f( OSS( '{' << s << '}' ) );
ostringstream oss;
oss << '{' << s << '}';
cout << oss.str() << endl;
}
it prints when run:
123hello}
{hello}
where 123 is the ASCII code for }. Why does using the macro get it wrong?
FYI: I'm currently using g++ 4.2.1 on Mac OS X as part of Xcode 3.x.
Solution I'm now using
class string_builder {
public:
template<typename T>
string_builder& operator,( T const &t ) {
oss_ << t;
return *this;
}
operator std::string() const {
return oss_.str();
}
private:
std::ostringstream oss_;
};
#define BUILD_STRING(...) (string_builder(), __VA_ARGS__)
using namespace std;
void f( string const &s ) {
cout << s << endl;
}
int main() {
char const *const s = "hello";
f( BUILD_STRING( '{', s, '}' ) );
}
std::ostringstream() is temporary which thus can be bound only to const references. Standalone operator<< (which take non const references as first argument) aren't considered and only the member one are. The best match in these for a char is converting the char to int.
This problems occurs often with string literals whose address is then displayed.
To solve the problem, the trick is to find a way to transform the temporary in a reference. The member operator<<s do that, but only the one for manipulator does it without side effect and only if the manipulator is a noop -- flush could be used. The members flush and write are also candidates. So for instance
#define OSS(...) \
dynamic_cast<std::ostringstream const&>(std::ostringstream().flush() << __VA_ARGS__).str()
A better thread-safe solution without involving the cumbersome macro.
The original call to function is this:
f( OSS( '{' << s << '}' ) );
How about if the call is just this:
f(stringbuilder() << '{' << s << '}' );
where stringbuilder is implemented as:
struct stringbuilder
{
std::ostringstream ss;
template<typename T>
stringbuilder & operator << (const T &data)
{
ss << data;
return *this;
}
operator string() { return ss.str(); }
};
void f( string const &s ) {
cout << s << endl;
}
Test:
int main() {
char const *const s = "hello";
f(stringbuilder() << '{' << s << '}' );
}
Output:
{hello}
Online Demo : http://ideone.com/QHFf4