mi sono imbattuto in questo problema di nuovo e si avvicinò con una versione più generale di soluzione di Sebastian Redl.
//given an index to replace at, a type to replace with and a tuple to replace in
//return a tuple of the same type as given, with the type at ReplaceAt set to ReplaceWith
template <size_t ReplaceAt, typename ReplaceWith, size_t... Idxs, typename... Args>
auto replace_type (std::index_sequence<Idxs...>, std::tuple<Args...>)
-> std::tuple<std::conditional_t<ReplaceAt==Idxs, ReplaceWith, Args>...>;
//instantiates a template with the types held in a tuple
template <template <typename...> class T, typename Tuple>
struct type_from_tuple;
template <template <typename...> class T, typename... Ts>
struct type_from_tuple<T, std::tuple<Ts...>>
{
using type = T<Ts...>;
};
//replaces the type used in a template instantiation of In at index ReplateAt with the type ReplaceWith
template <size_t ReplaceAt, typename ReplaceWith, class In>
struct with_n;
template <size_t At, typename With, template <typename...> class In, typename... InArgs>
struct with_n<At, With, In<InArgs...>>
{
using tuple_type = decltype(replace_type<At,With>
(std::index_sequence_for<InArgs...>{}, std::tuple<InArgs...>{}));
using type = typename type_from_tuple<In,tuple_type>::type;
};
//convenience alias
template <size_t ReplaceAt, typename ReplaceWith, class In>
using with_n_t = typename with_n<ReplaceAt, ReplaceWith, In>::type;
Vantaggi:
- selezione flessibile dei parametri di cambiare
- Non è necessario cambiare la classe originale
- Supporta le classi che hanno alcuni parametri senza default
options<int,long,int>
e with_n_t<2,int,options<>>
sono dello stesso tipo
Alcuni esempi di utilizzo:
with_n_t<1, int, options<>> a; //options<int, int, std::string>
with_n_t<2, int,
with_n_t<1, int, options<>>> b; //options<int, int, int>
Si potrebbe ulteriormente generalizzare questo per prendere coppie variadic di indici e tipi in modo che non c'è bisogno di nido with_n_t
.
'template using limited_options = options ;' potrebbe fare quello che stai chiedendo? Non penso che la parola chiave predefinita sia accettata in questo esempio (anche se avrebbe senso). –