Investigation: add a solution for default initialisation of missing arguments

...still somewhat unsatisfactory, because
- no clear compile error message when invoking pickArg with insufficient arguments
- the default initialisation case in SelectVararg is duplicated and messy
This commit is contained in:
Fischlurch 2017-09-28 02:25:32 +02:00
parent 3f9565a156
commit dc35a1a6e5
2 changed files with 27 additions and 10 deletions

View file

@ -95,21 +95,21 @@ using lib::meta::BuildIndexSeq;
using lib::meta::BuildIdxIter;
template<size_t i>
struct Pick
template<size_t i, typename INIT=void>
struct SelectVararg
{
template<typename ARG, typename...ARGS>
static auto
get (ARG, ARGS ...args)
{
return Pick<i-1>::get (args...);
return SelectVararg<i-1,INIT>::get (args...);
}
static auto get() { return nullptr; }
static INIT get() { return INIT{}; }
};
template<>
struct Pick<0>
template<typename INIT>
struct SelectVararg<0, INIT>
{
template<typename ARG, typename...ARGS>
static ARG
@ -118,9 +118,23 @@ struct Pick<0>
return a;
}
static auto get() { return nullptr; }
static INIT get() { return INIT{}; }
};
template<size_t idx, typename...ARGS>
constexpr inline auto
pickArg (ARGS... args)
{
return SelectVararg<idx>::get (args...);
}
template<size_t idx, typename INIT, typename...ARGS>
constexpr inline auto
pickInit (ARGS... args)
{
return SelectVararg<idx, INIT>::get (args...);
}
using Arr = std::array<int, 3>;
@ -130,8 +144,8 @@ template<size_t...idx1, size_t...idx2, typename...ARGS>
Arr
dispatch_ (IndexSeq<idx1...>,IndexSeq<idx2...>, ARGS...args)
{
Arr arr{Pick<idx1>::get(args...) ...};
fun2 (Pick<idx2>::get(args...) ...);
Arr arr{pickInit<idx1,int> (args...) ...};
fun2 (pickArg<idx2> (args...) ...);
return arr;
}
@ -158,6 +172,9 @@ main (int, char**)
auto arr = dispatch (2,3,4,5,6,7,8);
cout << util::join(arr) << "| " << showSizeof(arr) <<endl;
arr = dispatch (7,8);
cout << util::join(arr);
cout << "\n.gulp.\n";
return 0;

View file

@ -171,7 +171,7 @@ namespace meta {
using First = typename BuildIndexSeq<min(c,n)>::Ascending;
template<size_t c>
using After = typename BuildIndexSeq<max(size_t(0),n-c)>::template OffsetBy<c>;
using After = typename BuildIndexSeq< (n>c)? n-c : 0>::template OffsetBy<c>;
};
template<>