Re: Variadic templates
On 18 Nov., 02:32, Boris Rasin <rasin.bo...@gmail.com> wrote:
On Nov 14, 1:31 am, Boris Rasin <rasin.bo...@gmail.com> wrote:
I am thinking about possible implementation for a class to store
arbitrary number of objects of arbitrary types, just like tuple<>, but
with support for later (perfect) forwarding. As far as I understand,
the code in the simplified example below is not supported by c++0x. If
so, can someone explain why support for this case is not included in c+
+0x variadic templates? Is there an alternative implementation I am
missing?
template <class ... Args>
class store
{
public:
store (Args ... args) : members (args) ... {}
void forward() { some_func (members ...); }
Args ... members; // Error: template parameter pack expansion
not
supported in this context. Why not?
};
As Larry Evans pointed out to me, this was supported in the initial
variadic templates proposal (http://www.open-std.org/jtc1/sc22/wg21/
docs/papers/2004/n1704.pdf). Looks like it was dropped from a later
edition (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/
n2080.pdf) and it is not in the current draft. It would be interesting
to hear from someone who knows the reason for this removal, as it
doesn't seem to be possible to implement generic later forwarding
without this feature.
Maybe I'm too stupid to recognize the traps which you
obviously have in your mind. The following code bases
on the approach described in N2080 and compiles well
on ConceptGcc (It is more or less variadic version of
Alberto Barbati's proposal):
#include <concepts>
#include <cstddef>
#include <tuple>
#include <utility>
// <ext> (because ConceptGcc is not aware of the most
// recent standard draft)
namespace std {
auto concept IdentityOf<typename T> {
typename type = T;
requires SameType<type, T>;
}
template <IdentityOf T>
inline T&& forward(IdentityOf<T>::type&& t) { return t; }
}
//</ext>
template<std::size_t...> struct index_tuple{};
template<std::size_t I, typename IndexTuple, typename... Types>
struct make_indices_impl;
template<std::size_t I, std::size_t... Indices, typename T,
typename... Types>
struct make_indices_impl<I, index_tuple<Indices...>, T, Types...>
{
typedef typename make_indices_impl<I + 1, index_tuple<Indices...,
I>,
Types...>::type type;
};
template<std::size_t I, std::size_t... Indices>
struct make_indices_impl<I, index_tuple<Indices...> > {
typedef index_tuple<Indices...> type;
};
template<typename... Types>
struct make_indices : make_indices_impl<0, index_tuple<>, Types...>
{ };
template <class... Args>
void some_func(Args&&...){}
template <class... Args>
class store
{
public:
store(Args... args) : members(args...) {}
void forward() {
typedef typename make_indices<Args...>::type Indices;
return forward0(Indices(), members);
}
private:
template <std::size_t... Indices>
static void forward0(index_tuple<Indices...>, std::tuple<Args...>&&
args) {
some_func(std::forward<Args>(std::get<Indices>(args))...);
}
std::tuple<Args...> members;
};
int main() {
store<int, bool, double>(42, true, 1.2).forward();
}
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! ]