Prev: I keep running into long term c++ programmers who refuse to use exception
Next: display integer in MessageBox
From: PGK on 14 Mar 2010 20:35 In the class "Foo" below, is it possible to use a constructor initialization list to initialize "cs", a tuple of complex values? // #include <iostream>,<tuple>,<complex>,<type_traits> template <typename T, typename ... Ts> struct Foo { std::tuple<std::complex<T>, std::complex<Ts>...> cs; template<typename ... Us> Foo(T c1, T c2, Us ... ts) : ???? { } }; int main(int argc, char *argv[]) { Foo<int,bool,double> a(1,2,true,false,42.0,43.0); // For example } -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Daniel Krügler on 17 Mar 2010 12:12 On 15 Mrz., 12:35, PGK <graham.k...(a)gmail.com> wrote: > In the class "Foo" below, is it possible to use a constructor > initialization list to initialize "cs", a tuple of complex values? > > // #include <iostream>,<tuple>,<complex>,<type_traits> > > template <typename T, typename ... Ts> > struct Foo { > std::tuple<std::complex<T>, std::complex<Ts>...> cs; > > template<typename ... Us> > Foo(T c1, T c2, Us ... ts) : ???? { } > }; > > int main(int argc, char *argv[]) { > Foo<int,bool,double> a(1,2,true,false,42.0,43.0); // For example > } [It is unspecified whether std::complex can be instantiated with something else than a floating point type]. Try the following: #include <cstddef> #include <complex> #include <tuple> template<std::size_t...> struct indices{}; template<std::size_t I, class Indices, class Tuple, std::size_t N> struct pack_impl; template <std::size_t I, std::size_t... Indices, class Tuple, std::size_t N> struct pack_impl<I, indices<Indices...>, Tuple, N> { typedef pack_impl<I + 1, indices<Indices..., 2 * I>, Tuple, N> Next; typedef typename Next::index_values index_values; typedef typename Next::return_type return_type; }; template <std::size_t N, std::size_t... Indices, class Tuple> struct pack_impl<N, indices<Indices...>, Tuple, N> { typedef indices<Indices...> index_values; typedef std::tuple<std::complex<typename std::tuple_element< Indices, Tuple>::type>...> return_type; }; template<std::size_t Index, class Tuple> inline std::complex<typename std::tuple_element<Index, Tuple>::type> make_complex(const Tuple& ts) { return std::complex<typename std::tuple_element<Index, Tuple>::type>( std::get<Index>(ts), std::get<Index + 1>(ts)); } template<class Result, std::size_t... Indices, class Tuple> inline Result make_complex_tuple(indices<Indices...>, const Tuple& ts) { return Result(make_complex<Indices>(ts)...); } template<class... Types> struct pack { static_assert((sizeof...(Types) & 1) == 0, "variadic parameter number must be even"); typedef pack_impl<0, indices<>, std::tuple<Types...>, sizeof... (Types)/2> Impl; typedef typename Impl::return_type return_type; typedef typename Impl::index_values index_values; static return_type make(const Types&... ts) { return make_complex_tuple<return_type>(index_values(), std::make_tuple(ts...)); } }; template <typename T, typename ... Ts> struct Foo { private: std::tuple<std::complex<T>, std::complex<Ts>...> cs; public: template<typename... U, typename = typename std::enable_if< sizeof...(U) == 2 * sizeof...(Ts)>::type> Foo(T t1, T t2, U... us) : cs(pack<T, T, U...>::make(t1, t2, us...)) { } }; int main() { float f = 12.1; double d = 3.14; long double ld = 0.0; typedef Foo<double> F1; F1 x1(d, d); typedef Foo<float, double> F2; F2 x2(f, f, d, d); typedef Foo<float, double, long double> F3; F3 x3(f, f, d, d, ld, ld); } HTH & Greetings from Bremen, Daniel Kr�gler -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: PGK on 22 Mar 2010 23:05 Thanks Daniel. I've assembled a different solution with the intention to use decltype and auto, as well as tuple_cat for a recursive construction. Check it out: template <int I, int N, typename... Us> struct cmplx_helper { static auto cmplx (tuple<Us...> t) -> decltype (tuple_cat( make_tuple(complex<typename tuple_element<I,decltype (t)>::type> (get<I>(t),get<I+1>(t))), cmplx_helper<I+2,N,Us...>::cmplx(t))) { return tuple_cat( make_tuple(complex<typename tuple_element<I,decltype (t)>::type> (get<I>(t),get<I+1>(t))), cmplx_helper<I+2,N,Us...>::cmplx(t)); } }; template <int N, typename... Us> struct cmplx_helper <N,N,Us...> { static tuple<> cmplx(tuple<Us...> t) { return tuple<>(); } }; template <typename... Us> auto tuple_cmplx (tuple<Us...> t) -> decltype (cmplx_helper<0,tuple_size<tuple<Us...>>::value,Us...>::cmplx(t)) { return cmplx_helper<0,tuple_size<tuple<Us...>>::value,Us...>::cmplx(t); }; template <typename... Ts> class Foo { public: tuple<complex<Ts>...> cs; template <typename... Us, typename = typename std::enable_if< sizeof...(U) == 2 * sizeof...(Ts)>::type> Foo(Us... us) : cs(tuple_cmplx(tuple<Us...>(us...))) {} }; int main(int argc, char *argv[]) { Foo<bool,int,double> q(true,false,1,2,3.5,4.5); return 0; } -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Thomas Petit on 24 Mar 2010 15:17 On 23 mar, 15:05, PGK <graham.k...(a)gmail.com> wrote: > Thanks Daniel. I've assembled a different solution with the intention > to use decltype and auto, as well as tuple_cat for a recursive > construction. Check it out: > > // code... > Impressive ! But I don't get why you pass a list of single element instead of passing a list of std::pair. It makes the implementation so much simpler... And with intializer lists the calling point is quite elegant as well : #include <tuple> #include <complex> #include <utility> template <typename... Ts> struct Foo { std::tuple<std::complex<Ts>...> cs; Foo(std::pair<Ts, Ts>... ts) : cs(std::complex<Ts>(ts.first, ts.second)...){} }; int main(int argc, char *argv[]) { Foo<bool,int,double> foo( {true, false} , {1, 2} , {3.5, 4.5} ); return 0; } -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: PGK on 25 Mar 2010 08:32 Hi Thomas, > Impressive ! > Thankyou. > But I don't get why you pass a list of single element instead of > passing a list of std::pair. I would love to be able to choose that solution, but the interface I am faced with is already defined (to use single elements). Graham -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
|
Next
|
Last
Pages: 1 2 Prev: I keep running into long term c++ programmers who refuse to use exception Next: display integer in MessageBox |