Re: tuple in variadic template class constructor initialization list
On 15 Mrz., 12:35, PGK <graham.k...@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! ]