/* * ChangeLog: * 2014-05-21.0829 by LJEvans * downloaded from attachment to: * From: Roland Bock Newsgroups: gmane.comp.lib.boost.devel Subject: Re: [GSoC][MPL11] Post C++Now update Date: Wed, 21 May 2014 00:00:03 +0200 Lines: 137 Approved: news@gmane.org Message-ID: <537BD063.4070102@eudoxos.de> * * 2014-05-21.1136 by LJEvans * Reformatted and added many comments * to clarify how it works. */ #include #include namespace detail { struct any { template any(T&& t) /** * @brief * Provide a conversion constructor * for any type. */ { std::cout<<"any::CTOR:t="< struct first { typedef T type; }; template < typename ...Ts //sizeof...(Ts)+1 is the index of the argument desired //in the static select method below. > struct select_impl { template static U&& select ( typename first::type... //Produces sizeof...(Ts) any formal arguments. //Since each any can be constructed from //T&& for any T, the 1st sizeof...(Ts) //actual arguments to this function can //converted to an any. //This leaves the next , unconverted, actual arg //in argument list as the argument desired. , U&& u //the desired argument [the (sizeof...(Ts)+1)-th argument]. , Vs&&... ) { return static_cast(u); } }; template < std::size_t... Idx , typename... Ts > static auto select ( const std::index_sequence& , Ts&&... ts ) /** * @brief * Return (N+1)-th ts, where N=sizeof...(Idx). */ { return select_impl < decltype(Idx)... //converts std::size_t args to types(all of type std::size_t) //because called function uses detail::first metafunction //which requires type args. >::select ( static_cast(ts)... //forward the actual arguments. ); } }//exit detail namespace template auto nth(Ts &&...ts) /** * @brief * return (N+1)-th ts, where 0-th ts is first one. */ { return detail::select(std::make_index_sequence(), static_cast(ts)...); } int main() { { auto x = ::nth<7>(0,"1",'2',3,"4",'5',6,"7"); std::cout << x << std::endl; } { auto x = ::nth<0>(0,"1",'2',3,"4",'5',6,"7"); std::cout << x << std::endl; } { auto x = ::nth<1>(0,"1",'2',3,"4",'5',6,"7"); std::cout << x << std::endl; } return 0; }