On Tuesday, March 8, 2016 4:58 PM, Vladimir Batov
wrote: On 03/09/2016 08:43 AM, paul Fultz wrote: ...I guess people have different ways of learning a library. I wonder what is needed to be explained better in a initial overview of the library.
Please do not take it a a criticism of any kind. That's just an impression I've got. I could be way off the mark.. I often am... I read the docs... twice... well, I tried... :-) I was not able to find an answer to a nagging question -- why I might need the library? What does it do that the standard C++ does not? To me the Quick Start felt more like Quick Start to Confusion. :-) Literally I felt like the deeper into
the docs I was going the more alarmed I was.
Maybe I need a little more explanation of components in the Quick Start Guide. Perhaps, also, a comparison of writing some of the examples without using the library. The recursive print example is simple, but the technique could apply anytime you needed generic serialization of data. I have written code like that without using this library, so I can see benefit of using it for this particular case. So perhaps, writing a comparison without the library might make that clearer.
"We can make it (the functor) behave like a regular function"
I assume by functor, you mean function, as the library doesn't support functors and is beyond the scope of this library.
In all honesty I don't think I ever had such a need. Usually IMO the conversion is the other way around -- a reg. function into a functor. I
think it happens pretty much automatically.
Well, the library provides help for that as well, because currently in C++ you can't pass generic functions to other functions, like this: std::accumulate(v.begin(), v.end(), 0, std::max); // Compile error However, BOOST_FIT_LIFT will let you do that: std::accumulate(v.begin(), v.end(), 0, BOOST_FIT_LIFT(std::max));
"if we construct the class as a global variable"
Should I be excited about it? Globals are often a royal pain. Do I want
to construct it a a global variable? |
Whats the pain about these Global variables? They are const, can be
namespaced, and work just like free functions. However, they do have several
advantages.
First, by making them objects we can turn functions into first-class citizens.
This allows for functions to be easily passed around to other functions. In
fact, almost all the functions in this library are declared this way. This
make the functions(and adaptors) easily composable. For example, if you wanted
to write a function to do for_each over a tuple, you can easily compose the
`unpack` adaptor with the `by` adaptor:
BOOST_FIT_STATIC_FUNCTION(for_each_tuple) = compose(unpack, by);
So the `by` adaptor will call a function for each parameter, and the `unpack`
adaptor will unpack the elements of the tuple to each parameter. By composing
them together we can call a function for each element in a tuple. So, you can
write a function to print each value in a tuple, like this:
auto t = std::make_tuple(1, 2);
for_each_tuple([](auto x) { std::cout << x << std::endl; })(t);
So by passing functions to other functions, we can easily write some very
sophisticated functions without having to resort to metaprogramming. Just as a
comparison, here is how you could write for_each_tuple without this library:
namespace detail
{
template
"BOOST_FIT_STATIC_FUNCTION" | A macro? For C++14? Really? And given you mention it about 20 times just in the Quick Start section it seems quite pivotal for the library... Should I be excited about it? Macros are often a royal pain... Wrapping functors and lambdas in a macro?.. seems like I need quite a bit of
convincing I might want that.
C++17 will be adding support for inline variables, so in the future this macro will be unnecessary. For now, it will take care of statically initializing the function and avoiding possible ODR issues. Furthermore, dealing with inconsistencies and bugs across multiple platforms is a real pain. For example, MSVC has lots of bugs with constexpr that can affect statically initializing the function object. So this macro provides workarounds so the it can be initialized statically. I don't see the macro as problematic, and without the macro is more problematic. However, you can write it without the macro like this: template<class T> struct static_const_storage { static constexpr T value = T(); }; template<class T> constexpr T static_const_storage<T>::value; template<class T> constexpr const T& static_const_var(const T&) { return detail::static_const_storage<T>::value; } static constexpr auto&& for_each_tuple = static_const_var(compose(unpack, by)); This of course, will only work on a fairly compliant C++11 compilers. It doesn't work on MSVC. Also, it won't work when using lambdas. No doubt, C++14 gets rid of a lot of macro usages, but C++14 is still lacking in many areas, so macros are still needed to fill in these gaps.
For a library to be accepted the user has to understand the purpose/value of it and to get excited about it. I did not get it. In fact, I got the opposite... but I a not the brightest "bulb" in the
pack...
Thanks for the feedback, I probably should discuss more of the advantages of using function objects in the documentation to make it clear to more people.
V. ||
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost