The following simple code, compiled with -lboost_locale generates a bad cast exception. It is the same code in the boost tutorial itself. Any help?
#include <boost/locale.hpp>
#include <iostream>
int main()
{
using namespace boost::locale;
date_time now;
std::cout<<as::date<<now<<std::endl;
}
You need to imbue (global) locales:
Live On Coliru
#include <boost/locale.hpp>
#include <iostream>
int main() {
using namespace boost::locale;
boost::locale::generator gen;
std::locale loc = gen.generate(""); // or "C", "en_US.UTF-8" etc.
std::locale::global(loc);
std::cout.imbue(loc);
date_time_period_set things;
date_time now;
std::cout << as::date << now << std::endl;
}
Prints, e.g. on coliru:
09/17/15
Related
I am trying to convert boost::posix_time::ptime to YYMMDDHHMM format string. How to accomplish this?
Related: How to convert a boost::ptime to string
#include <iostream>
#include <cstdlib>
#include <string>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/format.hpp>
int main()
{
std::string submitDateString = "20190911T235959";
boost::posix_time::ptime submitPtime = boost::posix_time::from_iso_string( submitDateString );
// Use a facet to display time in a custom format (only hour and minutes).
std::stringstream sstream;
boost::posix_time::time_facet* facet = new boost::posix_time::time_facet();
facet->format("%y%m%d%H%M");
sstream.imbue(std::locale(std::locale::classic(), facet));
sstream << submitPtime;
std::cout << "submit date:" << sstream.str( ) << std::endl;
}
The following code fails to compile with 1.58 while it was compiling with 1.46. I guess it's a type conversion issue, but I can't make it right.
my code
#include <boost/filesystem.hpp>
#include <boost/range.hpp>
#include <boost/range/algorithm.hpp>
#include <boost/range/adaptors.hpp>
#include <vector>
using namespace boost;
using namespace filesystem;
using namespace adaptors;
int main(int argc, char ** argv)
{
recursive_directory_iterator beg = recursive_directory_iterator(".");
recursive_directory_iterator end = recursive_directory_iterator();
iterator_range<recursive_directory_iterator> files =
make_iterator_range(beg, end);
std::function<bool (path const & path)> fileFilter =
[](path const & path) -> bool {
return is_regular_file(path);
};
std::vector<path> paths;
copy(files | filtered(fileFilter), std::back_inserter(paths));
// works:
//copy(files, std::back_inserter(paths));
// also works:
//for(recursive_directory_iterator it = beg; it != end; ++it){
// if(fileFilter(*it)){
// paths.push_back(*it);
// }
//}
}
Error message (VS2010)
Error 1 error C2664:
'boost::filesystem::recursive_directory_iterator::recursive_directory_iterator(const
boost::filesystem::path
&,boost::filesystem::symlink_option::enum_type)' : cannot convert
parameter 1 from
'boost::iterators::detail::postfix_increment_proxy' to
'const boost::filesystem::path
&' [...]\boost\1.58.0_32\include\boost-1_58\boost\range\concepts.hpp 201 1 [...]
Can anyone help ?
Edit
Filed as https://svn.boost.org/trac/boost/ticket/11228.
This seems to be a bug introduced somewhere since Boost 1.55. Using boost 1.55 this compiles ok.
It could be this bug: https://svn.boost.org/trac/boost/ticket/10989
boost_1_57_0/boost/concept_check.hpp|210 col 13| error: conversion from ‘boost::iterators::single_pass_traversal_tag’ to non-scalar type ‘boost::iterators::forward_traversal_tag’ requested
The filtered adaptor requires the input to be forward_traversal tag. But recursive_directory_iterator only promises single_pass_traversal tag:
BOOST_RANGE_CONCEPT_ASSERT((
Convertible<
BOOST_DEDUCED_TYPENAME ForwardIteratorConcept::traversal_category,
forward_traversal_tag
>));
WORKAROUND
You can disable concept checks for now: -DBOOST_RANGE_ENABLE_CONCEPT_ASSERT=0:
Live On Coliru
#include <boost/filesystem.hpp>
#include <boost/range.hpp>
#include <boost/range/algorithm.hpp>
#include <boost/range/adaptors.hpp>
#include <vector>
#include <iostream>
namespace fs = boost::filesystem;
using namespace boost::adaptors;
int main() {
fs::recursive_directory_iterator beg("."), end;
auto fileFilter = [](fs::path const & path) { return is_regular_file(path); };
std::vector<fs::path> paths;
copy(boost::make_iterator_range(beg, end) | filtered(fileFilter), std::back_inserter(paths));
for(auto& p : paths)
std::cout << p << "\n";
}
Prints
"./main.cpp"
"./a.out"
I'm trying to pass variable number of ofstreams over to a function that accepts an initializer_list but doesn't seem to work and throws all possible errors from the initializer_list structure and about how my function is with an array of ofstreams cannot be matched to any defined function.
Is it actually possible to pass a reference of ofstreams over in an initializer_list?
test.cpp
#include "extension.h"
ofstream outputFile, outputFile2;
int main(void) {
outputFile.open(("data_1.txt");
outputFile2.open("data_2.txt");
writeSomething({outputFile, outputFile2});
outputFile.close();
outputFile2.close();
}
extension.h
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <iostream>
#include <fstream>
#include <unistd.h>
#include <string.h>
#include <initializer_list>
using namespace std;
void writeSomething(initializer_list<ofstream&> args);
extension.cpp
#include "extension.h"
void writeSomething(initializer_list<ofstream&> args) {
for (auto f : args ) {
f << "hello" << endl;
}
}
clang 3.4 (trunk 194324) produces a pretty clear error message:
initializer_list:54:23: error: 'iterator' declared as a pointer to a
reference of type
'std::basic_ofstream<char> &'
typedef const _E* iterator;
So no, it is not possible. See also Error: forming pointer to reference type 'const std::pair&'… I can't understand this error.
(gcc 4.7.2 and 4.8.1 crashes on this code due to some internal compiler error. I have submitted a bugreport.)
What you could do instead is to pass a pointer instead of a reference, something like this:
#include <fstream>
#include <initializer_list>
using namespace std;
void writeSomething(initializer_list<ofstream*> args) {
for (auto f : args )
*f << "hello" << endl;
}
int main() {
ofstream outputFile("data_1.txt");
ofstream outputFile2("data_2.txt");
writeSomething({&outputFile, &outputFile2});
}
However, I would much rather use a std::vector instead. Using an initializer list for this purpose is very strange and confusing for me.
I have read the other thread about copy or reference semantics for boost::spirt::qi::rule. I am using Boost 1.42.
using boost::spirit::qi::phrase_parse;
typedef boost::spirit::qi::rule < std::string::const_iterator, boost::spirit::ascii::space_type > rule_type;
std::list < rule_type > ruleList;
std::string const s("abcdef");
std::string::const_iterator iter = s.begin(), end = s.end();
std::cout << typeid(char_).name() << std::endl;
ruleList.push_back(char_);
ruleList.push_back(*ruleList.back());
assert(phrase_parse(iter, s.end(), ruleList.back(), boost::spirit::ascii::space));
assert(iter == s.end());
This fails with...
Assertion `phrase_parse(iter, s.end(), ruleList.back(), traits::space())' failed.
Aborted (core dumped)
Is there a way to store rules in a STL list or deque? (References don't die until removed).
With Boost V1.45, this (essentially your code from above) works without problems (MSVC2010, g++ 4.5.1):
#include <list>
#include <string>
#include <iostream>
#include <boost/spirit/include/qi.hpp>
using namespace boost::spirit;
int main()
{
typedef qi::rule<std::string::const_iterator, ascii::space_type> rule_type;
std::list<rule_type> ruleList;
std::string const s("abcdef");
std::string::const_iterator iter = s.begin(), end = s.end();
std::cout << typeid(qi::char_).name() << std::endl;
ruleList.push_back(qi::char_);
ruleList.push_back(*ruleList.back());
assert(qi::phrase_parse(iter, s.end(), ruleList.back(), ascii::space));
assert(iter == s.end());
return 0;
}
Therefore, I assume it's a bug in the version of Spirit you're using.
I could not get your example to compile. Aside from not using the correct types from ...::qi, you added a () to the trait::space type.
This works w/o problem for me (boost 1.44)
#include <boost/spirit/include/qi.hpp>
#include <string>
#include <vector>
#include <cassert>
using boost::spirit::qi::phrase_parse;
typedef boost::spirit::qi::rule < std::string::const_iterator, boost::spirit::qi::space_type > rule_type;
int main() {
std::list < rule_type > ruleList;
std::string const s("abcdef");
std::string::const_iterator iter = s.begin(), end = s.end();
ruleList.push_back(*boost::spirit::qi::char_);
assert(phrase_parse(iter, s.end(), ruleList.back(), boost::spirit::qi::space));
assert(iter == s.end());
}
~>g++ test.cpp && ./a.out
~>
please note I use qi::space_type and `qi::space instead of the ascii namespace. I have no idea what/where the trait namespace is.
I am trying to use a stringstream object in VC++ (VStudio 2003) butI am getting an error when I use the overloaded << operator to try and set some manipulators.
I am trying the following:
int SomeInt = 1;
stringstream StrStream;
StrStream << std::setw(2) << SomeInt;
This will not compile (error C2593: 'operator <<' is ambiguous).
Does VStudio 2003 support using manipulators in this way?
I know that I can just set the width directly on the stringstream object e.g. StrStream.width(2);
I was wondering why the more usual method doesn't work?
Are you sure you included all of the right headers? The following compiles for me in VS2003:
#include <iostream>
#include <sstream>
#include <iomanip>
int main()
{
int SomeInt = 1;
std::stringstream StrStream;
StrStream << std::setw(2) << SomeInt;
return 0;
}
I love this reference site for stream questions like this.
/Allan
You probably just forgot to include iomanip, but I can't be sure because you didn't include code for a complete program there.
This complete program works fine over here using VS 2003:
#include <sstream>
#include <iomanip>
int main()
{
int SomeInt = 1;
std::stringstream StrStream;
StrStream << std::setw(2) << SomeInt;
}