F
Frank Bergemann
Hi,
i have problems to create and forward tuple in MIL (member
initialization list).
Here's the program:
------------------------------- snip
--------------------------------------------------
#include <iostream>
#include <tuple>
template <typename T>
struct Elem
{
const T & _data;
Elem(const T & inp)
:_data(inp)
{ };
Elem(const Elem &)
{
std::cout << "!!! Elem copy c'tor invoked !!!" << std::endl;
};
};
template <typename T>
std:stream &
operator<<(
std:stream & out,
const Elem<T> & arg)
{
out << "Elem<T>(" << arg._data << ")";
return out;
}
/* Host class to actually hold tuple<> */
template <typename ...Types>
struct HostClassImpl
{
typedef typename std::tuple<Elem<Types>&&...> Type;
const Type _data;
HostClassImpl(Type && data)
: _data(data)
{ };
HostClassImpl(const HostClassImpl &)
{
std::cout << "HostClassImpl copy c'tor!" << std::endl;
};
HostClassImpl & operator=(const HostClassImpl &)
{
std::cout << "HostClassImpl assignment operator!" << std::endl;
return *this;
};
};
/*
* Host class front-end supporting variadic arguments
* just to enable the user level to do without std::forward_as_tuple()
* So HostClass actually shall do the std::forward_as_tuple() for the
user.
*/
template <typename ...Types>
struct HostClass
{
HostClassImpl<Types...> _impl;
template <typename ...Args>
HostClass(
Args&& ... args)
: _impl(std::forward_as_tuple(args...))
{ };
HostClass(const HostClass &)
{
std::cout << "HostClass copy c'tor!" << std::endl;
};
HostClass & operator=(const HostClass &)
{
std::cout << "HostClass assignment operator!" << std::endl;
return *this;
};
};
struct DummyHostClass
{
HostClassImpl<int, int, int> _impl;
DummyHostClass(void)
: _impl(std::forward_as_tuple(Elem<int>(10), Elem<int>(11),
Elem<int>(12)))
{
log();
};
void log(void)
{
std::cout << "DummyHostClass log data:" << std::endl;
std::cout << std::get<0>(_impl._data) << std::endl;
std::cout << std::get<1>(_impl._data) << std::endl;
std::cout << std::get<2>(_impl._data) << std::endl;
}
~DummyHostClass()
{
std::cout << "DummyHostClass d'tor" << std::endl;
};
};
int
main(
int argc,
char ** argv)
{
std::cout << std::endl << "Test (1): use Elem<int> only:" <<
std::endl;
Elem<int> elem(5);
std::cout << elem << std::endl;
std::cout << std::endl << "Test (2): create tuple<Elem<int>&&> - one
element only:" << std::endl;
std::tuple<Elem<int>&&> tuple(std::forward_as_tuple(Elem<int>(3)));
std::cout << std::get<0>(tuple) << std::endl;
std::cout << std::endl << "Test (3): create tuple<Elem<int>&&>,
Elem<int>&&> - two elements:" << std::endl;
std::tuple<Elem<int>&&, Elem<int>&&>
tuple2(std::forward_as_tuple(Elem<int>(5), Elem<int>(7)));
std::cout << std::get<0>(tuple2) << std::endl;
std::cout << std::get<1>(tuple2) << std::endl;
std::cout << std::endl << "Test (4): use HostClassImpl::Type
defnition for tuple<Elem<int>&&, Elem<int>&&> - two elements:" <<
std::endl;
HostClassImpl<int,int>::Type
tuple3(std::forward_as_tuple(Elem<int>(8), Elem<int>(9)));
std::cout << std::get<0>(tuple3) << std::endl;
std::cout << std::get<1>(tuple3) << std::endl;
std::cout << std::endl << "Test (5): use HostClassImpl c'tor passing
already constructed tuple:" << std::endl;
HostClassImpl<int, int> hostImpl(std::forward_as_tuple(Elem<int>(10),
Elem<int>(11)));
std::cout << std::get<0>(hostImpl._data) << std::endl;
std::cout << std::get<1>(hostImpl._data) << std::endl;
std::cout << std::endl << "Test (6): use DummyHostClass with fixed
HostClassImpl within:" << std::endl;
DummyHostClass dummy;
dummy.log();
#if 0
std::cout << std::endl << "Test (7): use HostClass c'tor passing
individual tuple element (variadic template):" << std::endl;
HostClass<int, int> host(Elem<int>(12), Elem<int>(13));
std::cout << std::get<0>(host._impl._data) << std::endl;
std::cout << std::get<1>(host._impl._data) << std::endl;
#endif
return 0;
}
------------------------------- snap
--------------------------------------------------
Here's the output:
------------------------------- snip
--------------------------------------------------
Test (1): use Elem<int> only:
Elem<T>(5)
Test (2): create tuple<Elem<int>&&> - one element only:
Elem<T>(3)
Test (3): create tuple<Elem<int>&&>, Elem<int>&&> - two elements:
Elem<T>(5)
Elem<T>(7)
Test (4): use HostClassImpl::Type defnition for tuple<Elem<int>&&,
Elem<int>&&> - two elements:
Elem<T>(8)
Elem<T>(9)
Test (5): use HostClassImpl c'tor passing already constructed tuple:
Elem<T>(10)
Elem<T>(11)
Test (6): use DummyHostClass with fixed HostClassImpl within:
DummyHostClass log data:
Elem<T>(10)
Elem<T>(11)
Elem<T>(12)
DummyHostClass log data:
Elem<T>(10)
Elem<T>(11871724)
Elem<T>(-1079275032)
DummyHostClass d'tor
------------------------------- snap
--------------------------------------------------
Why it the data away after leaving the constructor of DummyHostClass?
(Btw: 'DummyHostClass' is just a step towards intented 'HostClass' to
localize the problem.)
- many thanks!
best regards,
Frank
i have problems to create and forward tuple in MIL (member
initialization list).
Here's the program:
------------------------------- snip
--------------------------------------------------
#include <iostream>
#include <tuple>
template <typename T>
struct Elem
{
const T & _data;
Elem(const T & inp)
:_data(inp)
{ };
Elem(const Elem &)
{
std::cout << "!!! Elem copy c'tor invoked !!!" << std::endl;
};
};
template <typename T>
std:stream &
operator<<(
std:stream & out,
const Elem<T> & arg)
{
out << "Elem<T>(" << arg._data << ")";
return out;
}
/* Host class to actually hold tuple<> */
template <typename ...Types>
struct HostClassImpl
{
typedef typename std::tuple<Elem<Types>&&...> Type;
const Type _data;
HostClassImpl(Type && data)
: _data(data)
{ };
HostClassImpl(const HostClassImpl &)
{
std::cout << "HostClassImpl copy c'tor!" << std::endl;
};
HostClassImpl & operator=(const HostClassImpl &)
{
std::cout << "HostClassImpl assignment operator!" << std::endl;
return *this;
};
};
/*
* Host class front-end supporting variadic arguments
* just to enable the user level to do without std::forward_as_tuple()
* So HostClass actually shall do the std::forward_as_tuple() for the
user.
*/
template <typename ...Types>
struct HostClass
{
HostClassImpl<Types...> _impl;
template <typename ...Args>
HostClass(
Args&& ... args)
: _impl(std::forward_as_tuple(args...))
{ };
HostClass(const HostClass &)
{
std::cout << "HostClass copy c'tor!" << std::endl;
};
HostClass & operator=(const HostClass &)
{
std::cout << "HostClass assignment operator!" << std::endl;
return *this;
};
};
struct DummyHostClass
{
HostClassImpl<int, int, int> _impl;
DummyHostClass(void)
: _impl(std::forward_as_tuple(Elem<int>(10), Elem<int>(11),
Elem<int>(12)))
{
log();
};
void log(void)
{
std::cout << "DummyHostClass log data:" << std::endl;
std::cout << std::get<0>(_impl._data) << std::endl;
std::cout << std::get<1>(_impl._data) << std::endl;
std::cout << std::get<2>(_impl._data) << std::endl;
}
~DummyHostClass()
{
std::cout << "DummyHostClass d'tor" << std::endl;
};
};
int
main(
int argc,
char ** argv)
{
std::cout << std::endl << "Test (1): use Elem<int> only:" <<
std::endl;
Elem<int> elem(5);
std::cout << elem << std::endl;
std::cout << std::endl << "Test (2): create tuple<Elem<int>&&> - one
element only:" << std::endl;
std::tuple<Elem<int>&&> tuple(std::forward_as_tuple(Elem<int>(3)));
std::cout << std::get<0>(tuple) << std::endl;
std::cout << std::endl << "Test (3): create tuple<Elem<int>&&>,
Elem<int>&&> - two elements:" << std::endl;
std::tuple<Elem<int>&&, Elem<int>&&>
tuple2(std::forward_as_tuple(Elem<int>(5), Elem<int>(7)));
std::cout << std::get<0>(tuple2) << std::endl;
std::cout << std::get<1>(tuple2) << std::endl;
std::cout << std::endl << "Test (4): use HostClassImpl::Type
defnition for tuple<Elem<int>&&, Elem<int>&&> - two elements:" <<
std::endl;
HostClassImpl<int,int>::Type
tuple3(std::forward_as_tuple(Elem<int>(8), Elem<int>(9)));
std::cout << std::get<0>(tuple3) << std::endl;
std::cout << std::get<1>(tuple3) << std::endl;
std::cout << std::endl << "Test (5): use HostClassImpl c'tor passing
already constructed tuple:" << std::endl;
HostClassImpl<int, int> hostImpl(std::forward_as_tuple(Elem<int>(10),
Elem<int>(11)));
std::cout << std::get<0>(hostImpl._data) << std::endl;
std::cout << std::get<1>(hostImpl._data) << std::endl;
std::cout << std::endl << "Test (6): use DummyHostClass with fixed
HostClassImpl within:" << std::endl;
DummyHostClass dummy;
dummy.log();
#if 0
std::cout << std::endl << "Test (7): use HostClass c'tor passing
individual tuple element (variadic template):" << std::endl;
HostClass<int, int> host(Elem<int>(12), Elem<int>(13));
std::cout << std::get<0>(host._impl._data) << std::endl;
std::cout << std::get<1>(host._impl._data) << std::endl;
#endif
return 0;
}
------------------------------- snap
--------------------------------------------------
Here's the output:
------------------------------- snip
--------------------------------------------------
./main
Test (1): use Elem<int> only:
Elem<T>(5)
Test (2): create tuple<Elem<int>&&> - one element only:
Elem<T>(3)
Test (3): create tuple<Elem<int>&&>, Elem<int>&&> - two elements:
Elem<T>(5)
Elem<T>(7)
Test (4): use HostClassImpl::Type defnition for tuple<Elem<int>&&,
Elem<int>&&> - two elements:
Elem<T>(8)
Elem<T>(9)
Test (5): use HostClassImpl c'tor passing already constructed tuple:
Elem<T>(10)
Elem<T>(11)
Test (6): use DummyHostClass with fixed HostClassImpl within:
DummyHostClass log data:
Elem<T>(10)
Elem<T>(11)
Elem<T>(12)
DummyHostClass log data:
Elem<T>(10)
Elem<T>(11871724)
Elem<T>(-1079275032)
DummyHostClass d'tor
------------------------------- snap
--------------------------------------------------
Why it the data away after leaving the constructor of DummyHostClass?
(Btw: 'DummyHostClass' is just a step towards intented 'HostClass' to
localize the problem.)
- many thanks!
best regards,
Frank