
On 2012-04-03 15:57:34 +0000, Dave Abrahams said:
template <typename Then> struct otherwise { typedef Then type; static constexpr bool value = true; };
Do the uses of constexpr here add anything w.r.t. plain const?
Not to my knowledge (or correct me if it does!). I just acquired this habit from the way the C++11 standard library defined constants like the following in the FDIS: namespace std { template <class T, T v> struct integral_constant { static constexpr T value = v; typedef T value_type; typedef integral_constant<T,v> type; constexpr operator value_type() { return value; } }; }
5) Using nested variadic templates to get many template parameter packs to play with:
(...)
template <typename A, typename B> struct concat : detail::con<A>::template cat<B> {};
Interesting formulation. I used:
(...)
template <class ...T1s, class ...T2s> struct append_<vector<T1s...>, vector<T2s...> > : vector<T1s...,T2s...> {};
Ha! Obviously I had missed the possibility that you can have several parameter packs in a template specialization as long as the pack expansions don't appear subsequently in the signature.
Does the nested class template arrangement have any advantages?
I tried to think of some, but couldn't yet come up with any. I find your alternative even better.
6) Defining function result and result type at once.
Totally. I have used
// RETURNS() is used to avoid writing boilerplate "->decltype(x) { return x; }" phrases. // // USAGE: auto function(<arguments>) RETURNS(<some-expression>);
I like the trick of requiring a semicolon here.
Probably it's a good idea to incorporate noexcept: (...)
True. I decided to postpone the use of noexcept until I get other things to work, so I'm still missing all the little tricks there are with noexcept. (Keen to hear about them in May!)
It can't be used with recursive definitions like here, though:
// template <typename A, typename B, typename... C> // auto operator()(A const & a, B const & b, C const &... c) const -> // RETURNS(mul_()(a * b, c...))
// --> Error: invalid use of incomplete type mul_
Heh, try (*this) instead of mul_(). That works until you try to incorporate noexcept as suggested above (at least on GCC 4.7).
Yep, same thing on clang: as soon as I enable noexcept in the RETURNS(...) macro, it gives "error: invalid use of 'this' outside of a nonstatic member function".
// ****** workaround ****** static mul_ get() noexcept { return mul_(); }
I'm not sure which one is correct here, GCC or Clang, but but this trick had a similar result: "error: calling 'get' with incomplete return type 'mul_'". The only alternative way I could fix it was to define a function returning a reference, e.g.: struct mul_ { // ... static mul_ const & get() noexcept; }; constexpr mul_ mul = {}; inline mul_ const & mul_::get() noexcept { return mul; }
very annoying.
Indeed.
7) Counted template recursion.
Isn't it a bit slicker to do this by creating an argument pack of integers and expanding that with get<Is>(t)... ?
Oh, sure! I wonder how I missed that. Yes, converting a template argument pack into an equal-length index sequence is very useful.
--8<---------------cut here---------------start------------->8--- template <class T, T I, class S> struct cons_c;
template <template <class T, T...> class S, class T, T I, T ...Is> struct cons_c<T, I, S<T, Is...> > : S<T,I,Is...> {};
template <class T, T ...Is> struct vector_c { typedef vector_c type; };
template <std::size_t N> struct count_ : cons_c<std::size_t, N-1, typename count_<N-1>::type> {};
template <> struct count_<0> : vector_c<std::size_t> {};
template <std::size_t N> using count = typename count_<N>::type;
#include <tuple>
template <typename F, typename Tuple , std::size_t ...Is> auto apply_tuple(F f, Tuple const & t, vector_c<std::size_t, Is...>) RETURNS(f(std::get<Is>(t)...));
template <typename F, typename ...T> auto apply_tuple(F f, std::tuple<T...> const & t) RETURNS(apply_tuple(f, t, count<sizeof...(T)>())); --8<---------------cut here---------------end--------------->8---
So thanks, I'm happy to hide this trick into my sleeve! ;) -- Pyry Jahkola · http://pyrtsa.posterous.com pyry.jahkola@iki.fi · http://twitter.com/pyrtsa Attending C++Now! 2012