I'm working on a mix-in type Config Reader class which supports reading configuration data from environment, command line, files, etc..
I was kind of following the std::tuple type design:
template <class... Ts> struct ConfigReader {};
template <class T, class... Ts>
class ConfigReader<T, Ts...> : ConfigReader<Ts...>
{
public:
typedef boost::fusion::set<T, Ts...> sequence_type;
ConfigReader(T t, Ts... ts)
: ConfigReader<Ts...>(ts...)
, parameters_(t, ts...)
{
this->init();
}
private:
sequence_type parameters_;
void init()
{
boost::fusion::for_each(parameters_, SetFromEnvironment());
boost::fusion::for_each(parameters_, SetFromCommandLine());
boost::fusion::for_each(parameters_, SetFromConfigFile());
}
};
But I realized that I could also define this without the recursive inheritance
template <class T, class... Ts>
class ConfigReader<T, Ts...>
{
public:
typedef boost::fusion::set<T, Ts...> sequence_type;
ConfigReader(T t, Ts... ts)
: parameters_(t, ts...)
{
this->init();
}
template <class Type>
typename boost::fusion::result_of::value_at_key<Sequence const, Type>::type get()
{
return boost::fusion::at_key<Type>(parameters);
}
private:
sequence_type parameters_;
void init()
{
boost::fusion::for_each(parameters_, SetFromEnvironment());
boost::fusion::for_each(parameters_, SetFromCommandLine());
boost::fusion::for_each(parameters_, SetFromConfigFile());
}
};
The latter case seems to work better because init() is only called once which is really what I want. But now I'm confused as to what are the differences between the two? Am I losing something without the recursive inheritance?
Simplified usage would be.. (Ignoring Parameter type structs)
int main()
{
ConfigReader<Start, End, Resources> configReader(Start(), End("infinity"), Resources());
Start startTime = configReader.get<Start>();
}
The recursive approach makes no sense. Consider an example case where you want:
ConfigReader<A, B, C> reader(A{}, B{}, C{});
In the recursive case, you end up with this hierarchy:
ConfigReader<A, B, C> has three readers: A, B, C
|
|
V
ConfigReader<B, C> has two readers: B, C
|
|
V
ConfigReader<C> has one reader: C
You have 6 readers, when you meant for only 3! What you probably meant when you did the recursive hierarchy is for each instantiation to just have one reader: not all of them. That is:
template <typename T, typename... Ts>
struct ConfigReader : ConfigReader<Ts...> {
T current;
ConfigReader(T t, Ts... ts)
: ConfigReader<Ts...>(ts...)
, current(t)
{ }
};
But what you're doing with the boost fusion set accomplishes that directly. Though, with C++11, you should probably just stick with:
template <typename... T>
struct ConfigReader {
std::tuple<T...> readers;
};
It should suit your purpose.
Related
I've written (in c++11) a variadic template constexpr function which calculates max sizeof of the parameter types, e.g.:
maxSizeof<int, char, MyType>()
That works correctly. Then I would like to have a variadic template class with a field which is an array of size equal to the maxSizeof(). That should also work correctly:
template <typename... TypesT>
class Myclass {
uint8_t field[maxSizeOf<TypesT...>()]
}
But I also need Myclass to declare methods for each of the parameter types. I've used CRTP for that in following way:
template <typename... TypesT>
class Myclass;
template <>
class Myclass {
uint8_t field[maxSizeOf<TypesT...>()] // (1) Couldn't do it here as there are no `TypesT`
}
template <typename FirstT, typename... OtherT>
class Myclass<FirstT, OtherT...> : public Myclass<OtherT...> {
public:
virtual void doSomething(FirstT object) = 0;
private:
uint8_t field[maxSizeOf<FirstT, OtherT...>()] // (2) Shouldn't do it here as it will create field for all of the "middle" classes
}
The question is how implement the declarations of the methods and in the same time have the array field with proper size. (1) and (2) doesn't work for the reasons stated in comments.
Like most SW engineering problems, this can be solved by adding more layers of indirection[1]:
template <typename... TypesT>
class MyclassFunctions;
template <>
class MyclassFunctions
{};
template <typename FirstT, typename... OtherT>
class MyclassFunctions<FirstT, OtherT> : public MyClassFunctions<OtherT...>
{
public:
virtual void doSomething(FirstT object) = 0;
};
template <typename... TypesT>
class Myclass : public MyclassFunctions<TypesT...>
{
uint8_t field[maxSizeOf<TypesT...>()]
};
There are two problems here. The first is getting it to compile. The second is to be able to call doSomething.
The easy solution to the first problem is:
template <class T>
class MyClassFunction {
public:
virtual void doSomething(T object) = 0;
};
template <typename... TypesT>
class MyClass : public MyClassFunction<TypesT>...
{
uint8_t field[maxSizeOf<TypesT...>()];
};
this has the disadvantage that calls to doSomething can be hard to do:
prog.cpp:33:59: error: request for member ‘doSomething’ is ambiguous
using foo = decltype( ((MyClass<int, char>*)nullptr)->doSomething(7) );
^~~~~~~~~~~
we need some usings to fix this. In c++17 we could just do:
template <typename... TypesT>
class MyClass : public MyClassFunction<TypesT>...
{
uint8_t field[maxSizeOf<TypesT...>()];
public:
using MyClassFunction<TypesT>::doSomething...;
};
but that isn't available in c++11.
To fix this we have to do a tree-based inheritance. The easiest tree-based is linear:
template<class...Ts>
struct MyClassFunctions {};
template<class T0, class T1, class...Ts>
struct MyClassFunctions<T0, T1, Ts...>:
MyClassFunction<T0>, MyClassFunctions<T1, Ts...>
{
using MyClassFunction<T0>::doSomething;
using MyClassFunctions<T1, Ts...>::doSomething;
};
template<class T0>
struct MyClassFunctions:MyClassFunction<T0> {};
template <typename... TypesT>
class MyClass : public MyClassFunctions<TypesT...>
{
uint8_t field[maxSizeOf<TypesT...>()];
};
Live example.
This has the disadvantage of creating O(n^2) total type name length, which can cause problems for long lists of types. At medium length you get memory bloat and compile time slowdown, at long length you get compilers crashing.
To get around that you can build a binary tree of inheritance. The trick is to be able to split a ... pack in half using log-depth template recursion. Once you have that, the code becomes:
template<class T0, class T1, class...Ts>
struct MyClassFunctions<T0, T1, Ts...>:
left_half< MyClassFunctions, T0, T1, Ts... >,
right_half< MyClassFunctions, T0, T1, Ts... >
{
using left_half< MyClassFunctions, T0, T1, Ts... >::doSomething;
using right_half< MyClassFunctions, T0, T1, Ts... >::doSomething;
};
however this effort is only worthwhile if you have more than a few dozen types being passed in.
left/right half look like this:
template<template<class...>class Z, class...Ts>
using left_half = /* todo */;
template<template<class...>class Z, class...Ts>
using right_half = /* todo */;
with some crazy metaprogramming in todo.
You can use the indexes trick and the machinery of std::tuple to split those lists (in c++11 log-depth index generation takes a bit of effort). Or you can do an exponential split on the type list.
Write
template<class...Ts>
struct pack {};
template<std::size_t N, class Pack>
struct split/* {
using lhs = // part before N
using rhs = // part after N
};
that splits a type list with the first N being on the left. It can be written recursively:
template<std::size_t N, class...Ts>
struct split<N, pack<Ts...>> {
private:
using half_split = split<N/2, pack<Ts...>>;
using second_half_split = split<N-N/2, typename half_split::rhs>;
public:
using lhs = concat< typename half_split::lhs, typename second_half_split::lhs >;
using rhs = typename second_half_split::rhs;
};
template<class...Ts>
struct split<0, pack<Ts...>> {
using lhs=pack<>;
using rhs=pack<Ts...>;
};
template<class T0, class...Ts>
struct split<1, pack<T0, Ts...>> {
using lhs=pack<T0>;
using rhs=pack<Ts...>;
};
this requires concat<pack, pack> to do the obvious thing.
Now you need apply<template, pack> and then write left_half and right_half.
To sum up Angew answer, and the accessiblity problem pointed out by Yakk, you can reapply the Angew's engineering principle:
template <typename... TypesT>
class MyclassFunctions;
template <>
class MyclassFunctions<>
{};
template <typename FirstT>
class MyclassFunctions<FirstT>
{
public:
virtual void doSomething(FirstT object){};
};
template <typename FirstT, typename... OtherT>
class MyclassFunctions<FirstT, OtherT...> : public MyclassFunctions<OtherT...>
{
public:
using MyclassFunctions<OtherT...>::doSomething;
virtual void doSomething(FirstT object){};
};
template <typename... TypesT>
class Myclass : public MyclassFunctions<TypesT...>
{
int field[sizeof...(TypesT)];
};
One way to do it is to exploit an old trick well known to users of functional programming languages: Recursing on a partial result, e.g. the accumulated maximum as first template parameter. To maintain the Myclass<Ts...> signature, however, we then need to add a level of indirection, as Angew suggested:
template<std::size_t curMax, typename... Ts>
struct MyclassImpl
{
std::uint8_t field[curMax];
};
template<std::size_t curMax, typename T1, typename... Ts >
struct MyclassImpl<curMax, T1, Ts...> : MyclassImpl<(curMax > sizeof(T1) ? curMax : sizeof(T1)), Ts...>
{
virtual void doSomething(T1) = 0;
};
template<typename... Ts>
using Myclass = MyclassImpl<0u, Ts...>;
Let's add a primitive test case (you can also make use of maxSizeof here):
struct TestStruct{ char c[100]; };
using TestMC = Myclass<int, double, TestStruct, short>;
static_assert( sizeof(TestMC::field) == sizeof(TestStruct), "Field size incorrect" );
While this is not better than Angew's version (other than not requiring maxSizeof), it's still a good opportunity to point out this useful recursion pattern. Mostly but not only in pure functional programming languages like Haskell, it is very useful for enabling tail-call optimization, e.g.:
-- slowMax "tail call unfriendly"
-- (optional) signature
slowMax :: Ord a => [a] -> a
slowMax [x] = x
slowMax (x:xs) = let m = slowMax xs in if x > m then x else m
-- fastMax "tail call friendly"
fastMax :: Ord a => [a] -> a
fastMax (x:xs) = fastMaxImpl x xs where
fastMaxImpl m [] = m
fastMaxImpl m (x:xs) = fastMaxImpl (if x > m then x else m) xs
(In a simple test I made with -O2, fastMax was 3.5x faster.)
Is there a way to automatically select between multiple non-template functions based on a template parameter?
Example:
class Aggregate
{
public:
std::string asString();
uint32_t asInt();
private:
// some conglomerate data
};
template <typename T>
T get(Aggregate& aggregate)
{
// possible map between types and functions?
return bind(aggregate, typeConvert[T])(); ??
// or
return aggregate.APPROPRIATE_TYPE_CONVERSION();
}
The solution would be nice to throw a compiler error if there is no good conversion available, i.e.
get<double>(aggregate); // compile error
I do not want to use template specialization, i.e
template<>
int get(Aggregate& aggregate)
{
return aggregate.asInt();
}
because it leads to code duplication when your get() function has more then one line of code
The pedestrian way is to define each possible option separately:
template <typename T> T get(Aggregate &); // leave undefined
template <> uint32_t get(Aggregate & a) { return a.asInt(); }
// ...
Absent any more systematic structure that encodes which function serves which conversion, I think this is the best you can do. It may be worth redefining Aggregate, though, to be more introspectible.
You may do something like (require C++11) : (https://ideone.com/UXrQFm)
template <typename T, typename... Ts> struct get_index;
template <typename T, typename... Ts>
struct get_index<T, T, Ts...> : std::integral_constant<std::size_t, 0> {};
template <typename T, typename Tail, typename... Ts>
struct get_index<T, Tail, Ts...> :
std::integral_constant<std::size_t, 1 + get_index<T, Ts...>::value> {};
template <typename T, typename Tuple> struct get_index_in_tuple;
template <typename T, typename ... Ts>
struct get_index_in_tuple<T, std::tuple<Ts...>> : get_index<T, Ts...> {};
class Aggregate
{
public:
std::string asString();
uint32_t asInt();
private:
// some conglomerate data
};
template <typename T>
T get(Aggregate& aggregate)
{
using types = std::tuple<uint32_t, std::string>;
auto funcs = std::make_tuple(&Aggregate::asInt, &Aggregate::asString);
return (aggregate.* (std::get<get_index_in_tuple<T, types>::value>(funcs)))();
}
I have a template:
template<typename... Ts> //T1,T2,T3,...
struct foo {
//my struct
};
I want to do static_assert checks on T1,T3,T5,... (the "odd types") and on T2,T4,T6,... (the "even types") separately.
I have found this simple solution:
template<size_t N, typename... Ts>
struct perform_checks {};
template<size_t N, typename T, typename U, typename... Ts>
struct perform_checks<N, T, U, Ts...> : perform_checks<N, Ts...>
{
//check for odd types
static_assert(std::is_default_constructible<T>::value,"failure");
//check for even types
static_assert(std::is_copy_constructible<U>::value,"failure");
};
The N parameter allows it to end. I use it like this:
template<typename... Ts>
struct foo {
perform_checks<0,Ts...> hello;
};
This seems to be working fine. But is it possible to avoid the hello variable? I never use it for any other purpose.
Derive foo from perform_checks<> privately:
template <typename... Ts> struct foo : private perform_checks<Ts...> {
// stuff
};
Oh, and get rid of the N parameter that you don't need:
template <typename... Ts> struct perform_checks {};
template <typename T> struct perform_checks<T> {
template <typename U> struct dependent_name_hack : std::false_type {};
static_assert(dependent_name_hack<T>::value,
"Odd number of parameters not acceptable.");
};
template <typename T, typename U, typename... Ts>
struct perform_checks<T, U, Ts...> : perform_checks<Ts...> {
//check for odd types
static_assert(std::is_default_constructible<T>::value,"failure");
//check for even types
static_assert(std::is_copy_constructible<U>::value,"failure");
};
You can use enable_if1 (and boost::mpl) in more-or-less the following way:
#include <boost/mpl/and.hpp>
template<size_t N, typename... Ts>
struct perform_checks {};
template<size_t N, typename T, typename U, typename... Ts>
struct perform_checks<N, T, U, Ts...> : perform_checks<N, Ts...>
{
typedef boost::mpl::and_<std::is_default_constructible<T>::type,
std::is_copy_constructible<U>::type> type;
};
template < class... Ts,
class = typename std::enable_if<perform_checks<0, Ts...>::type>
struct foo {
//my struct
};
The only purpose of foo in the OP is triggering the check when it's instantiated. That's why you need the variable hello: it's an instantiation of foo.
I would rather follow the approach of traits in <type_traits>. More precisely, I would turn perform_checks into class (or struct) that has public static constexpt bool member called value which is true or false depending on whether the given types pass the test or not. Then I would use a single static_assert to stop compilation if value is false.
My solution, which assumes that the number of template type arguments is even, follows:
#include <type_traits>
template<typename First, typename Second, typename... Others>
struct perform_checks :
std::integral_constant<bool,
perform_checks<First, Second>::value && // Checks First and Second
perform_checks<Others...>::value // Recursively "calls" itself on Others
> {
};
// This specialization finishes the recursion and effectively performs the test
template<typename First, typename Second>
struct perform_checks<First, Second> :
std::integral_constant<bool,
std::is_default_constructible<First>::value && // Checks First
std::is_copy_constructible<Second>::value // Checks Second
> {
};
Here is a simple test:
struct NonDefaultConstructible {
NonDefaultConstructible() = delete;
};
struct NonCopyConstructible {
NonCopyConstructible(const NonCopyConstructible&) = delete;
};
int main() {
static_assert(perform_checks<int, double>::value, "Failure");
static_assert(perform_checks<int, int, double, double>::value, "Failure");
static_assert(!perform_checks<NonDefaultConstructible, int>::value, "Failure");
static_assert(!perform_checks<int, NonCopyConstructible>::value, "Failure");
static_assert(!perform_checks<int, int, double, NonCopyConstructible>::value, "Failure");
}
Notice that no variable was created.
I'd like to be able to do this:
template<typename Mix>
struct A {
A(int i) { }
};
template<typename Mix>
struct B {
B() { }
B(const char*) { }
};
template<template<typename> class... Mixins>
struct Mix : Mixins<Mix<Mixins...>>... {
// This works, but forces constructors to take tuples
template<typename... Packs>
Mix(Packs... packs) : Packs::Type(packs.constructorArgs)... { }
};
template<template<typename> class MixinType, typename... Args>
struct ArgPack {
typedef MixinType Type; // pretend this is actually a template alias
tuple<Args...> constructorArgs;
ArgPack(Args... args) : constructorArgs(args...) { }
}
template<typename... Args>
ArgPack<A, Args...> A_(Args... args) {
return ArgPack<A, Args...>(args...);
}
template<typename... Args>
ArgPack<B, Args...> B_(Args... args) {
return ArgPack<B, Args...>(args...);
}
Mix<A, B> m(); // error, A has no default constructor
Mix<A, B> n(A_(1)); // A(int), B()
Mix<A, B> n(A_(1), B_("hello"); // A(int), B(const char*)
How do I fill in /* mysterious code here */ to do what I want, to provide a nice interface for calling some set of constructors of mixins? I have a solution that works by making all non-null constructs actually take a tuple of args, and then overloading figures out which one to call, but I would like to avoid constraining mixin authors by making them write a constructor A(tuple), instead of just A(int, int).
Thanks!
I think I understand what you want. std::pair has a similar feature:
std::pair<T, U> p(std::piecewise_construct
, std::forward_as_tuple(foo, bar)
, std::forward_as_tuple(qux) );
// p.first constructed in-place as if first(foo, bar) were used
// p.second constructed in place as if second(qux) were used
As you can see this has a lot of benefits: exactly one T and U construction each takes place, neither T and U are required to be e.g. MoveConstructible, and this only costs the constructions of two shallow tuples. This also does perfect forwarding. As a warning though, this is considerably harder to implement without inheriting constructors, and I will use that feature to demonstrate a possible implementation of a piecewise-constructor and then attempt to make a variadic version of it.
But first, a neat utility that always come in handy when variadic packs and tuples are involved:
template<int... Indices>
struct indices {
using next = indices<Indices..., sizeof...(Indices)>;
};
template<int Size>
struct build_indices {
using type = typename build_indices<Size - 1>::type::next;
};
template<>
struct build_indices<0> {
using type = indices<>;
}
template<typename Tuple>
constexpr
typename build_indices<
// Normally I'd use RemoveReference+RemoveCv, not Decay
std::tuple_size<typename std::decay<Tuple>::type>::value
>::type
make_indices()
{ return {}; }
So now if we have using tuple_type = std::tuple<int, long, double, double>; then make_indices<tuple_type>() yields a value of type indices<0, 1, 2, 3>.
First, a non-variadic case of piecewise-construction:
template<typename T, typename U>
class pair {
public:
// Front-end
template<typename Ttuple, typename Utuple>
pair(std::piecewise_construct_t, Ttuple&& ttuple, Utuple&& utuple)
// Doesn't do any real work, but prepares the necessary information
: pair(std::piecewise_construct
, std::forward<Ttuple>(ttuple), std::forward<Utuple>(utuple)
, make_indices<Ttuple>(), make_indices<Utuple>() )
{}
private:
T first;
U second;
// Back-end
template<typename Ttuple, typename Utuple, int... Tindices, int... Uindices>
pair(std::piecewise_construct_t
, Ttuple&& ttuple, Utuple&& utuple
, indices<Tindices...>, indices<Uindices...>)
: first(std::get<Tindices>(std::forward<Ttuple>(ttuple))...)
, second(std::get<Uindices>(std::forward<Utuple>(utuple))...)
{}
};
Let's try plugging that with your mixin:
template<template<typename> class... Mixins>
struct Mix: Mixins<Mix<Mixins...>>... {
public:
// Front-end
template<typename... Tuples>
Mix(std::piecewise_construct_t, Tuples&&... tuples)
: Mix(typename build_indices<sizeof...(Tuples)>::type {}
, std::piecewise_construct
, std::forward_as_tuple(std::forward<Tuples>(tuples)...)
, std::make_tuple(make_indices<Tuples>()...) )
{
// Note: GCC rejects sizeof...(Mixins) but that can be 'fixed'
// into e.g. sizeof...(Mixins<int>) even though I have a feeling
// GCC is wrong here
static_assert( sizeof...(Tuples) == sizeof...(Mixins)
, "Put helpful diagnostic here" );
}
private:
// Back-end
template<
typename TupleOfTuples
, typename TupleOfIndices
// Indices for the tuples and their respective indices
, int... Indices
>
Mix(indices<Indices...>, std::piecewise_construct_t
, TupleOfTuples&& tuple, TupleOfIndices const& indices)
: Mixins<Mix<Mixins...>>(construct<Mixins<Mix<Mixins...>>>(
std::get<Indices>(std::forward<TupleOfTuples>(tuple))
, std::get<Indices>(indices) ))...
{}
template<typename T, typename Tuple, int... Indices>
static
T
construct(Tuple&& tuple, indices<Indices...>)
{
using std::get;
return T(get<Indices>(std::forward<Tuple>(tuple))...);
}
};
As you can see I've gone one level higher up with those tuple of tuples and tuple of indices. The reason for that is that I can't express and match a type such as std::tuple<indices<Indices...>...> (what's the relevant pack declared as? int...... Indices?) and even if I did pack expansion isn't designed to deal with multi-level pack expansion too much. You may have guessed it by now but packing it all in a tuple bundled with its indices is my modus operandi when it comes to solving this kind of things... This does have the drawback however that construction is not in place anymore and the Mixins<...> are now required to be MoveConstructible.
I'd recommend adding a default constructor, too (i.e. Mix() = default;) because using Mix<A, B> m(std::piecewise_construct, std::forward_as_tuple(), std::forward_as_tuple()); looks silly. Note that such a defaulted declaration would yield no default constructor if any of the Mixin<...> is not DefaultConstructible.
The code has been tested with a snapshot of GCC 4.7 and works verbatim except for that sizeof...(Mixins) mishap.
I faced a very similar problem in the context of a Policy based design. Basically i have my class inherit behaviour from a set of Policies, and some of them are stateful and need constructor initialization.
The solution i found is to have the policy classes organized in a deep hierarchy, instead of a wide one. This allows to write constructors which take just the elements they need from an argument pack and pass along the remaining pack to initialize the "top" part of the hierarchy.
Here is my code:
/////////////////////////////////////////////
// Generic part //
/////////////////////////////////////////////
template<class Concrete,class Mother,class Policy>
struct PolicyHolder{};
struct DeepHierarchyFinal{};
template<class Concrete,class P,typename... Args>
struct DeepHierarchy: public PolicyHolder<Concrete,DeepHierarchy<Concrete,Args...>,P>,
public P
{
template<typename... ConstructorArgs>
DeepHierarchy(ConstructorArgs... cargs):
PolicyHolder<Concrete,DeepHierarchy<Concrete,Args...>,P>(cargs...){};
};
template<class Concrete,class P>
struct DeepHierarchy<Concrete,P>: public PolicyHolder<Concrete,DeepHierarchyFinal,P>,
public P
{
template<typename... ConstructorArgs>
DeepHierarchy(ConstructorArgs... cargs):
PolicyHolder<Concrete,DeepHierarchyFinal,P>(cargs...){};
};
///////////////////////////////////////////
// Test case //
///////////////////////////////////////////
///////////////////////////////////////////
// Policies //
///////////////////////////////////////////
struct Policy1{};
struct Policy2{};
struct Policy3{};
struct Policy4{};
template<class Concrete,class Mother>
struct PolicyHolder<Concrete,Mother,Policy1> : public Mother
{
int x;
template<typename... Args>
PolicyHolder(int _x,Args... args):Mother(args...),x(_x) {};
};
template<class Concrete,class Mother>
struct PolicyHolder<Concrete,Mother,Policy2> : public Mother
{
template<typename... Args>
PolicyHolder(Args... args):Mother(args...){
cout<<"Policy2 initialized";
// Here is a way to know (at runtime) if a particular
// policy has been selected in the concrete class
if (boost::is_convertible<Concrete,Policy3>::value)
cout<<" together with Policy3\n";
else
cout<<" without Policy3\n";
};
};
template<class Concrete,class Mother>
struct PolicyHolder<Concrete,Mother,Policy3> : public Mother
{
string s;
char c;
template<typename... Args>
PolicyHolder(string _s,char _c,Args... args):Mother(args...), s(_s),c(_c) {};
};
template<class Concrete,class Mother>
struct PolicyHolder<Concrete,Mother,Policy4> : public Mother
{
template<typename... Args>
PolicyHolder(Args... args):Mother(args...) {
// Here is a way to check (at compile time) that 2 incompatible policies
// does not coexist
BOOST_STATIC_ASSERT(( ! boost::is_convertible<Concrete,Policy1>::value));
};
};
//////////////////////////////////////////////
// Concrete class //
//////////////////////////////////////////////
template<class... PoliciesPack>
struct C: public DeepHierarchy<C<PoliciesPack...>,PoliciesPack...>
{
using Policies=DeepHierarchy<C<PoliciesPack...>,PoliciesPack...>;
string s;
template<typename... Args>
C(string _s,Args... args):Policies(args...),s(_s){};
};
BOOST_AUTO_TEST_CASE( testDeepHierarchyConstruction )
{
C<Policy1,Policy2> c0("foo",4);
BOOST_CHECK_EQUAL(c0.x,4);
C<Policy1,Policy2,Policy3> c1("bar",3,"foo",'f');
BOOST_CHECK_EQUAL(c1.c,'f');
C<Policy3,Policy4> c2("rab","oof",'d');
BOOST_CHECK_EQUAL(c2.c,'d');
}
I made a more extensive analisys of this approach at this page.
I have a class template and I can't seem to figure out how to perform a Variadic Template style instantiation.
Here is the "code" so far of what I'm looking for:
template<typename _Classname, typename... Args>
class CFunctorStartExT
{
friend class CXXFactory;
protected:
template<typename U>
CFunctorStartExT(typename U& _functor, Args&... args) :
m_Functor(_functor),
m_args(args)
{
}
virtual bool ProcessLoop(CSomeClass* pThread)
{
return m_Functor(pThread, m_args);
}
protected:
_Classname& m_Functor;
Args... m_args;
};
Obviously this won't compile :). The idea is to create a class that can store the values passed in (if any.. it might just have _Classname/U defined) on the constructor so they can be retrieved later to pass to m_Functor in another function.
First: can Variadic Template even be done in VS2010? I am getting compile problems just with the template declaration error C2143: syntax error : missing ',' before '...' from the line template<typename _Classname, typename... Args>
Second, can what I am trying to accomplish be done? Thanks!
Visual C++ 2010 does not support variadic templates.
I believe the following will do what you want. First you need a utility:
// make_tuple_indices
template <size_t...> struct tuple_indices {};
template <size_t _Sp, class _IntTuple, size_t _Ep>
struct make_indices_imp;
template <size_t _Sp, size_t ..._Indices, size_t _Ep>
struct make_indices_imp<_Sp, tuple_indices<_Indices...>, _Ep>
{
typedef typename make_indices_imp<_Sp+1, tuple_indices<_Indices..., _Sp>, _Ep>::type type;
};
template <size_t _Ep, size_t ..._Indices>
struct make_indices_imp<_Ep, tuple_indices<_Indices...>, _Ep>
{
typedef tuple_indices<_Indices...> type;
};
template <size_t _Ep, size_t _Sp = 0>
struct make_tuple_indices
{
static_assert(_Sp <= _Ep, "make_tuple_indices input error");
typedef typename make_indices_imp<_Sp, tuple_indices<>, _Ep>::type type;
};
Then you can use this to help you expand a tuple holding your arguments:
template<typename _Classname, typename... Args>
class CFunctorStartExT
{
friend class CXXFactory;
protected:
template<typename U>
CFunctorStartExT(U& _functor, Args&... args) :
m_Functor(_functor),
m_args(args...)
{
}
virtual bool ProcessLoop(CSomeClass* pThread)
{
return ProcessLoop(pThread,
typename make_tuple_indices<sizeof...(Args)>::type());
}
protected:
_Classname& m_Functor;
std::tuple<Args...> m_args;
private:
template <std::size_t ...Indx>
bool ProcessLoop(CSomeClass* pThread, tuple_indices<Indx...>)
{
return m_Functor(pThread, std::get<Indx>(m_args)...);
}
};
As far as VS2010 variadic template support: I have no idea.
Variadic templates are a patch upon a kludge upon a hack -- you're not going to enjoy this. The way to do this (off the top of my head) is to use template specialization together with inheritance. Something along these lines:
template<typename Classname, typename... Args>
class CFunctorStartExT;
template<typename Classname, typename Arg0, typename... Args>
class CFunctorStartExT : private CFunctorStartExT<Classname, Args...> {
protected:
Arg0 m_arg;
};
template<typename Classname>
class CFunctorStartExT {
protected:
Classname &m_Functor;
};
I've never done this before, and haven't tested it, but this is the general idea. You could have a look at a std::tuple implementation for something that actually works.