How to work out types required for std::for_each lambda function - c++11

I am confused about how to work out what type is required to use a lambda function in std::for_each. It seems I cannot use auto in this case as a parameter (Visual Studio 2013 complains anyway).
In the code below I would have thought I would use sections as the type for the for_each function, but in fact I have to use
const std::pair<std::string, std::unordered_map<std::string, std::string> >
And for the 'inner' type in this case what do I use?
My main question is how I work out what type to use?
#include <iostream>
#include <string>
#include <unordered_map>
#include <algorithm>
// key=value pairs within a section
typedef std::unordered_map<std::string, std::string> keyvalue;
// [section1] - top level
typedef std::unordered_map< std::string, std::unordered_map<std::string, std::string> > sections;
class config
{
public:
config() {
setup();
}
typedef sections::iterator iterator;
iterator begin() { return sections_.begin(); }
iterator end() { return sections_.end(); }
private:
sections sections_;
void setup() {
// obviously we wouldn't hard code like this in a real program
sections_["programming languages"].insert(std::make_pair("C", "imperative"));
sections_["programming languages"].insert(std::make_pair("C++", "OOP"));
sections_["programming languages"].insert(std::make_pair("Java", "OOP"));
sections_["programming languages"].insert(std::make_pair("Haskell", "functional"));
sections_["programming languages"].insert(std::make_pair("Prolog", "logic"));
}
};
int main() {
config cfg;
std::for_each(cfg.begin(), cfg.end(), [](const std::pair<std::string, std::unordered_map<std::string, std::string> > sec) {
std::cout << "section name: " << sec.first << std::endl;
// what is inner type - thought it would be keyvalue ???
//std::for_each(sec.second.begin(), sec.second.end(), [](const keyvalue& pr) {
//std::cout << "first: " << pr << std::endl;
//});
});
// I thought type would be sections ???
//std::for_each(cfg.begin(), cfg.end(), [](const sections& sec) {
// std::cout << "section name: " << sec.first << std::endl;
//});
}

You can also use decltype for this purpose like this:
config cfg;
std::for_each(cfg.begin(), cfg.end(), [](const decltype(*cfg.begin())& sec) {
std::cout << "section name: " << sec.first << std::endl;
std::for_each(sec.second.begin(), sec.second.end(), [](const decltype(*sec.second.begin())& pr) {
std::cout << "first: " << pr.first << std::endl;
});
});
I'm not 100% certain how reference types affect this, so removing it might be more appropriate like const std::remove_reference<decltype(*cfg.begin())>::type& sec
Although it should be noted that VS2013 ItelliSense has trouble with decltype and will mark it as an error even if it compiles fine.
STL containers always define a value_type so in that case you can use decltype(inst)::value_type and you don't need the remove_reference shenanigans. So I would advise you to also add a value_type typedef to your type like this:
class config
{
public:
typedef sections::value_type value_type;
Then you can do:
config cfg;
std::for_each(cfg.begin(), cfg.end(), [](const decltype(cfg)::value_type& sec) {
std::cout << "section name: " << sec.first << std::endl;
std::for_each(sec.second.begin(), sec.second.end(), [](const decltype(sec.second)::value_type& pr) {
std::cout << "first: " << pr.first << std::endl;
});
});

Related

How to make recursive Spirit X3 parser with a separate visitor class

A parser application where I’m working on calls for recursive rules. Besides looking into the Recursive AST tutorial examples of Boost Spirit X3 which can be found here:
https://www.boost.org/doc/libs/develop/libs/spirit/doc/x3/html/index.html, I was looking for a solution with a std::variant of some types as well as a std::vector of that same
variant type.
In the StackOverflow post titled: Recursive rule in Spirit.X3, I found the code from the answer from sehe a decent starting point for my parser.
I have repeated the code here but I have limited the input strings to be tested. Because the full list from the original is not relevant for this question here.
//#define BOOST_SPIRIT_X3_DEBUG
#include <iostream>
#include <boost/fusion/adapted.hpp>
#include <boost/spirit/home/x3.hpp>
#include <string>
#include <vector>
#include <variant>
struct value: std::variant<int,float,std::vector<value>>
{
using base_type = std::variant<int,float,std::vector<value>>;
using base_type::variant;
friend std::ostream& operator<<(std::ostream& os, base_type const& v) {
struct {
std::ostream& operator()(float const& f) const { return _os << "float:" << f; }
std::ostream& operator()(int const& i) const { return _os << "int:" << i; }
std::ostream& operator()(std::vector<value> const& v) const {
_os << "tuple: [";
for (auto& el : v) _os << el << ",";
return _os << ']';
}
std::ostream& _os;
} vis { os };
return std::visit(vis, v);
}
};
namespace parser {
namespace x3 = boost::spirit::x3;
x3::rule<struct value_class, value> const value_ = "value";
x3::rule<struct o_tuple_class, std::vector<value> > o_tuple_ = "tuple";
x3::real_parser<float, x3::strict_real_policies<float> > float_;
const auto o_tuple__def = "tuple" >> x3::lit(':') >> ("[" >> value_ % "," >> "]");
const auto value__def
= "float" >> (':' >> float_)
| "int" >> (':' >> x3::int_)
| o_tuple_
;
BOOST_SPIRIT_DEFINE(value_, o_tuple_)
const auto entry_point = x3::skip(x3::space) [ value_ ];
}
int main()
{
for (std::string const str : {
"float: 3.14",
"int: 3",
"tuple: [float: 3.14,int: 3]",
"tuple: [float: 3.14,int: 3,tuple: [float: 4.14,int: 4]]"
}) {
std::cout << "============ '" << str << "'\n";
//using boost::spirit::x3::parse;
auto first = str.begin(), last = str.end();
value val;
if (parse(first, last, parser::entry_point, val))
std::cout << "Parsed '" << val << "'\n";
else
std::cout << "Parse failed\n";
if (first != last)
std::cout << "Remaining input: '" << std::string(first, last) << "'\n";
}
}
However I would like to use a traditional visitor class rather than making ostream a friend in the variant class. You know just a struct/class with a bunch of function objects for each type you encounter in the variant and a "for loop" for the vector that calls std::visit for each
element.
My goal for the traditional visitor class is to be able to maintain a state machine during printing.
My own attempts to write this visitor class did fail because I ran into an issue with my GCC 8.1 compiler. With GCC during compilation std::variant happens to be std::variant_size somehow and I got the following error:
error: incomplete type 'std::variant_size' used in nested name specifier
More about this here:
Using std::visit on a class inheriting from std::variant - libstdc++ vs libc++
Is it possible giving this constraint on GCC to write a visitor class for the code example I included, so that the ostream stuff can be removed?
Is it possible giving this constraint on GCC to write a visitor class for the code example I included, so that the ostream stuff can be removed?
Sure. Basically, I see three approaches:
1. Add the template machinery
You can specialize the implementation details accidentally required by GCC:
struct value: std::variant<int,float,std::vector<value>> {
using base_type = std::variant<int,float,std::vector<value>>;
using base_type::variant;
};
namespace std {
template <> struct variant_size<value> :
std::variant_size<value::base_type> {};
template <size_t I> struct variant_alternative<I, value> :
std::variant_alternative<I, value::base_type> {};
}
See it live on Wandbox (GCC 8.1)
2. Don't (again live)
Extending the std namespace is fraught (though I think it's legal for
user-defined types). So, you can employ my favorite pattern and hide th
estd::visit dispatch in the function object itself:
template <typename... El>
void operator()(std::variant<El...> const& v) const { std::visit(*this, v); }
Now you can simply call the functor and it will automatically dispatch
on your own variant-derived type because that operator() overload does
NOT have the problems that GCC stdlib has:
if (parse(first, last, parser::entry_point, val))
{
display_visitor display { std::cout };
std::cout << "Parsed '";
display(val);
std::cout << "'\n";
}
3. Make things explicit
I like this the least, but it does have merit: there's no magic and no
tricks:
struct value: std::variant<int,float,std::vector<value>> {
using base_type = std::variant<int,float,std::vector<value>>;
using base_type::variant;
base_type const& as_variant() const { return *this; }
base_type& as_variant() { return *this; }
};
struct display_visitor {
void operator()(value const& v) const { std::visit(*this, v.as_variant()); }
// ...
Again, live
SUMMARY
After thinking a bit more, I'd recommend the last approach, due to the relative simplicity. Clever is often a code-smell :)
Full listing for future visitors:
//#define BOOST_SPIRIT_X3_DEBUG
#include <iostream>
#include <boost/fusion/adapted.hpp>
#include <boost/spirit/home/x3.hpp>
#include <string>
#include <vector>
#include <variant>
struct value: std::variant<int,float,std::vector<value>> {
using base_type = std::variant<int,float,std::vector<value>>;
using base_type::variant;
base_type const& as_variant() const { return *this; }
base_type& as_variant() { return *this; }
};
struct display_visitor {
std::ostream& _os;
void operator()(value const& v) const { std::visit(*this, v.as_variant()); }
void operator()(float const& f) const { _os << "float:" << f; }
void operator()(int const& i) const { _os << "int:" << i; }
void operator()(std::vector<value> const& v) const {
_os << "tuple: [";
for (auto& el : v) {
operator()(el);
_os << ",";
}
_os << ']';
}
};
namespace parser {
namespace x3 = boost::spirit::x3;
x3::rule<struct value_class, value> const value_ = "value";
x3::rule<struct o_tuple_class, std::vector<value> > o_tuple_ = "tuple";
x3::real_parser<float, x3::strict_real_policies<float> > float_;
const auto o_tuple__def = "tuple" >> x3::lit(':') >> ("[" >> value_ % "," >> "]");
const auto value__def
= "float" >> (':' >> float_)
| "int" >> (':' >> x3::int_)
| o_tuple_
;
BOOST_SPIRIT_DEFINE(value_, o_tuple_)
const auto entry_point = x3::skip(x3::space) [ value_ ];
}
int main()
{
for (std::string const str : {
"float: 3.14",
"int: 3",
"tuple: [float: 3.14,int: 3]",
"tuple: [float: 3.14,int: 3,tuple: [float: 4.14,int: 4]]"
}) {
std::cout << "============ '" << str << "'\n";
//using boost::spirit::x3::parse;
auto first = str.begin(), last = str.end();
value val;
if (parse(first, last, parser::entry_point, val))
{
display_visitor display { std::cout };
std::cout << "Parsed '";
display(val);
std::cout << "'\n";
}
else
std::cout << "Parse failed\n";
if (first != last)
std::cout << "Remaining input: '" << std::string(first, last) << "'\n";
}
}

How to Avoid Copies When Doing Method Chaining in C++

I love to use method chaining to completely initialize objects and then store them in const variables. When analyzing the resulting code it turns out that this means the execution of many copy constructors. Therefore I have wondered whether C++ 11 move semantics might help optimizing method chaining.
Indeed I have been able to significantly speed up my code by adding overloads with ref qualifiers to my chain methods. Please consider this source code:
#include <chrono>
#include <iostream>
#include <string>
#undef DEBUGGING_OUTPUT
#undef ENABLE_MOVING
class Entity
{
public:
Entity() :
data(0.0), text("Standard Text")
{
#ifdef DEBUGGING_OUTPUT
std::cout << "Constructing entity." << std::endl;
#endif
}
Entity(const Entity& entity) :
data(entity.data), text(entity.text)
{
#ifdef DEBUGGING_OUTPUT
std::cout << "Copying entity." << std::endl;
#endif
}
Entity(Entity&& entity) :
data(entity.data), text(std::move(entity.text))
{
#ifdef DEBUGGING_OUTPUT
std::cout << "Moving entity." << std::endl;
#endif
}
~Entity()
{
#ifdef DEBUGGING_OUTPUT
std::cout << "Cleaning up entity." << std::endl;
#endif
}
double getData() const
{
return data;
}
const std::string& getText() const
{
return text;
}
void modify1()
{
data += 1.0;
text += " 1";
}
Entity getModified1() const &
{
#ifdef DEBUGGING_OUTPUT
std::cout << "Lvalue version of getModified1" << std::endl;
#endif
Entity newEntity = *this;
newEntity.modify1();
return newEntity;
}
#ifdef ENABLE_MOVING
Entity getModified1() &&
{
#ifdef DEBUGGING_OUTPUT
std::cout << "Rvalue version of getModified1" << std::endl;
#endif
modify1();
return std::move(*this);
}
#endif
void modify2()
{
data += 2.0;
text += " 2";
}
Entity getModified2() const &
{
#ifdef DEBUGGING_OUTPUT
std::cout << "Lvalue version of getModified2" << std::endl;
#endif
Entity newEntity = *this;
newEntity.modify2();
return newEntity;
}
#ifdef ENABLE_MOVING
Entity getModified2() &&
{
#ifdef DEBUGGING_OUTPUT
std::cout << "Rvalue version of getModified2" << std::endl;
#endif
modify2();
return std::move(*this);
}
#endif
private:
double data;
std::string text;
};
int main()
{
const int interationCount = 1000;
{
// Create a temporary entity, modify it and store it in a const variable
// by taking use of method chaining.
//
// This approach is elegant to write and read, but it is slower than the
// other approach.
const std::chrono::steady_clock::time_point startTimePoint =
std::chrono::steady_clock::now();
for (int i = 0; i < interationCount; ++i)
{
const Entity entity = Entity().getModified1().getModified1().getModified2().getModified2();
#ifdef DEBUGGING_OUTPUT
std::cout << "Entity has text " << entity.getText() << " and data "
<< entity.getData() << std::endl;
#endif
}
const std::chrono::steady_clock::time_point stopTimePoint =
std::chrono::steady_clock::now();
const std::chrono::duration<double> timeSpan = std::chrono::duration_cast<
std::chrono::duration<double>>(stopTimePoint - startTimePoint);
std::cout << "Method chaining has taken " << timeSpan.count() << " seconds."
<< std::endl;
}
{
// Create an entity and modify it without method chaining. It cannot be
// stored in a const variable.
//
// This approach is optimal from a performance point of view, but it is longish
// and renders usage of a const variable impossible even if the entity
// won't change after initialization.
const std::chrono::steady_clock::time_point startTimePoint =
std::chrono::steady_clock::now();
for (int i = 0; i < interationCount; ++i)
{
Entity entity;
entity.modify1();
entity.modify1();
entity.modify2();
entity.modify2();
#ifdef DEBUGGING_OUTPUT
std::cout << "Entity has text " << entity.getText() << " and data "
<< entity.getData() << std::endl;
#endif
}
const std::chrono::steady_clock::time_point stopTimePoint =
std::chrono::steady_clock::now();
const std::chrono::duration<double> timeSpan = std::chrono::duration_cast<
std::chrono::duration<double>>(stopTimePoint - startTimePoint);
std::cout << "Modification without method chaining has taken "
<< timeSpan.count() << " seconds." << std::endl;
}
return 0;
}
The version without method chaining is approximately 10 times faster here than the other one. As soon as I replace
#undef ENABLE_MOVING
by
#define ENABLE_MOVING
the version without method chaining remains only 1.5 times faster than the other one. So this is a great improvement.
Still I wonder whether I could optimize the code even more. When I switch to
#define DEBUGGING_OUTPUT
then I can see that there are new entities created for every call to getModified1() or getModified2(). The only advantage of move construction is that creation is cheaper. Is there a way to even prevent move construction and work on the original entity with method chaining?
With the help of Igor Tandetnik I guess that I can answer my question!
The modification methods have to be changed to return rvalue references:
#ifdef ENABLE_MOVING
Entity&& getModified1() &&
{
#ifdef DEBUGGING_OUTPUT
std::cout << "Rvalue version of getModified1" << std::endl;
#endif
modify1();
return std::move(*this);
}
#endif
#ifdef ENABLE_MOVING
Entity&& getModified2() &&
{
#ifdef DEBUGGING_OUTPUT
std::cout << "Rvalue version of getModified2" << std::endl;
#endif
modify2();
return std::move(*this);
}
#endif
and the initialization has to happen like this:
const Entity entity = std::move(Entity().getModified1().getModified1().getModified2().getModified2());
Then the method chaining code is almost as efficient as the other code. The difference is one call to the move constructor and one additional destructor call for the temporary instance which is negligible.
Thank you for your help!

boost spirit debug rule with locals

I fail to compile code in debug mode (code with BOOST_SPIRIT_DEBUG_NODE(my_rule)) when my_rule has some local variable of custom type.
First version with rule qi::locals<std::string> is OK
Second version with rule qi::locals<std::string,int> is still OK
Current version with rule qi::locals<std::string,std::vector<int> > does not compile.
error: no match for operator<< (operand types are std::basic_ostream<char> and const std::vector<int>)
I declare streaming operator<< :
std::ostream& > operator<< (std::ostream& os, std::vector<int> const& art)
But It still does not compile.
I use boost 1_64_0. Here is the smallest complete code:
#define BOOST_SPIRIT_DEBUG
#if !defined(BOOST_SPIRIT_DEBUG_OUT)
#define BOOST_SPIRIT_DEBUG_OUT std::cerr
#endif
#include <tuple>
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_fusion.hpp>
#include <boost/spirit/include/phoenix_stl.hpp>
#include <boost/spirit/include/phoenix_object.hpp>
#include <iostream>
#include <string>
#include <vector>
// To solve the pb of declaration of grammar with locals
#include <typeinfo>
std::ostream&
operator<< (std::ostream& os, std::vector<int> const& art)
{
os << "[";
for( auto it = art.begin(); it != art.end() ; it++ ) {
os << *it << ",";
}
os << "]";
return os;
}
namespace client
{
namespace phoenix = boost::phoenix;
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
using phoenix::val;
using namespace qi::labels;
using qi::_val;
using qi::_1;
// Our number list parser
template <typename Iterator>
struct mini_wkart_grammar
// first version: : qi::grammar<Iterator, int(), qi::locals<std::string>, ascii::space_type>
// second version: : qi::grammar<Iterator, int(), qi::locals<std::string,int>, ascii::space_type>
: qi::grammar<Iterator, std::vector<int>(), qi::locals<std::string,std::vector<int> >, ascii::space_type>
{
mini_wkart_grammar() : mini_wkart_grammar::base_type(start,"numbers")
{
using phoenix::push_back;
// first version: start= (qi::int_ >> qi::char_(',') >> qi::int_)[_val=_1+_3];
// second version: start= (qi::int_[_b=_1] >> qi::char_(',') >> qi::int_[_b+=_1])[_val=_b];
start= (qi::int_[push_back(_b,_1)] >> qi::char_(',') >> qi::int_[push_back(_b,_1)])[_val=_b];
BOOST_SPIRIT_DEBUG_NODE(start);
}
// first version OK: qi::rule<Iterator, int(), qi::locals<std::string>, ascii::space_type> start;
// second version OK: qi::rule<Iterator, int(), qi::locals<std::string,int>, ascii::space_type> start;
qi::rule<Iterator, std::vector<int>(), qi::locals<std::string,std::vector<int> >, ascii::space_type> start;
};
}
////////////////////////////////////////////////////////////////////////////
// Main program
////////////////////////////////////////////////////////////////////////////
int
main()
{
std::cout << "/////////////////////////////////////////////////////////\n\n";
std::cout << "\t\tA comma separated list parser for Spirit...\n\n";
std::cout << "/////////////////////////////////////////////////////////\n\n";
std::cout << "Give me a comma separated list of numbers.\n";
std::cout << "Type [q or Q] to quit\n\n";
// std::string result;
// first ans second version: int result;
std::vector<int> result;
std::string str;
using boost::spirit::ascii::space;
client::mini_wkart_grammar<std::string::const_iterator> wkart_grammar;
while (getline(std::cin, str))
{
if (str.empty() || str[0] == 'q' || str[0] == 'Q')
break;
std::string::const_iterator iter = str.begin();
std::string::const_iterator end = str.end();
// if (client::parse_numbers(str.begin(), str.end()))
if (boost::spirit::qi::phrase_parse(iter, end, wkart_grammar, space, result))
{
std::cout << "-------------------------\n";
std::cout << "Parsing succeeded\n";
std::cout << result << " Parses OK: " << std::endl;
}
else
{
std::cout << "-------------------------\n";
std::cout << "Parsing failed\n";
std::cout << "-------------------------\n";
}
}
std::cout << "Bye... :-) \n\n";
return 0;
}
I think miss something in the operator declaration?
Thanks for any help..
First Off...
What are you trying to achieve anyways? That whole grammar could be start = qi::int_ % ','; and still have the exact same effect. See Boost Spirit: “Semantic actions are evil”?
Your Question:
Sadly you need to make that operator<< ADL-enabled. (http://en.cppreference.com/w/cpp/language/adl)
Since the element type is primitive, there is no associated namespace. So the only namespace that will be tried is namespace ::std which declared std::vector<>.
namespace std {
std::ostream &operator<<(std::ostream &os, vector<int> const &art) {
os << "[";
for (auto it = art.begin(); it != art.end(); it++) {
os << *it << ",";
}
os << "]";
return os;
}
}
That might have undesired side effects, you you may want to force the issue with a hack:
namespace ADL_Hack {
template <typename T>
struct allocator : std::allocator<T> { };
}
template <typename T>
using Vector = std::vector<T, ADL_Hack::allocator<T> >;
namespace ADL_Hack {
template <typename... Ts>
std::ostream &operator<<(std::ostream &os, std::vector<Ts...> const &art) {
os << "[";
for (auto it = art.begin(); it != art.end(); it++) {
os << *it << ",";
}
os << "]";
return os;
}
}
See it Live On Wandbox

Understand C++11 solution for checking the existence of a member function

https://stackoverflow.com/a/31860104
#include <iostream>
#include <string>
template<class T>
auto optionalToString(T* obj)
-> decltype( obj->toString() )
{
return obj->toString();
}
auto optionalToString(...) -> std::string
{
return "toString not defined";
}
struct TA
{
std::string toString() const
{
return "Hello";
}
};
struct TB
{
};
Question> Given the proposed solution optionalToString, how I can use it to detect that TA has toString while TB doesn't.
A solution using can_apply from this code:
template<class T>
using toString_result = decltype(std::declval<T>().toString());
template<class T>
constexpr auto has_toString = can_apply<toString_result, T>::value;
Used like this:
struct TA
{
std::string toString() const
{
return "Hello";
}
};
struct TB
{
};
int main()
{
std::cout << has_toString<TA> << '\n';
std::cout << has_toString<TB> << '\n';
return 0;
}
DEMO
The given solution allows you to always get a string from any object. If it has a toString() member function, this will be used, otherwise, a default string. Usage example, given the above:
TA a;
TB b;
std::cout << "a: " << optionalToString(&a) << '\n';
std::cout << "b: " << optionalToString(&b) << std::endl;
However, you will not get a boolean value whether a or b has a toString() method. If you want that, you need something like the solution proposed by O'Neil.

segfault when accessing static std::map

I'm trying to refactor a rather complicated piece of code and run into segfaults during loading the library. This is a minimal example of what I could single out to be the source of the segfault:
#include <iostream>
#include <string>
#include <map>
class Manager {
public:
class Action{
};
static bool registerAction(const Action* a, const char* name);
};
namespace Actions {
class ExampleAction : public Manager::Action {
};
namespace {
static bool available = Manager::registerAction(new ExampleAction(),"ExampleAction");
}
}
namespace {
typedef std::map<const std::string,const Manager::Action*> ActionList;
static ActionList sActions;
}
bool Manager::registerAction(const Action* a, const char* name){
std::cout << "attempting to register action " << a << " as " << name << std::endl;
sActions[name] = a;
std::cout << "done" << std::endl;
return true;
}
int main(){
std::cout << "hello!" << std::endl;
for(auto it:sActions){
std::cout << it.first << std::endl;
}
std::cout << "world!" << std::endl;
return 0;
}
It compiles fine with g++ 4.8.4 using the --std=c++11 flag, but upon execution, this happens:
attempting to register action 0x1ebe010 as ExampleAction
Segmentation fault (core dumped)
The line attempting to register comes first, which is of course expected, but the line assigning the value to the static map instance causes the crash, and I don't understand the reason. I'm probably being stupid here, but still - any suggestions on how to fix this?

Resources