如何更改 C++ 中的第 n 个模板参数?
How to change the nth template parameter in C++?
如果我使用以下类型:
template<uint64_t f1 = 0, uint64_t f2 = 0, uint64_t f3 = 0, ..., uint64_t f10 = 0>
class Options;
using myOpts = Options<51, 8, 12>;
无论如何我可以做一些等效于这个伪代码的事情吗:
using newOpts = myOpts[6]<82>;
这将保留所有现有的模板参数并将第 7 个设置为 82
。
我提出一个模板using
如下
template <std::size_t Idx, std::uint64_t NewVal, typename MO>
using NewOpts = decltype(get_new_opt<Idx, NewVal>(std::declval<MO>()));
其中 get_new_opts()
和 get_new_opts_helper()
仅声明辅助函数如下
template <std::size_t Idx, std::uint64_t NewVal, std::uint64_t ... Fs,
std::size_t ... Is>
constexpr auto get_new_opt_helper (Options<Fs...>,
std::index_sequence<Is...>)
-> std::remove_reference_t<
decltype( std::declval<Options<(Idx == Is ? NewVal : Fs)...>>() )>;
template <std::size_t Idx, std::uint64_t NewVal, std::uint64_t ... Fs>
constexpr auto get_new_opt (Options<Fs...> o)
-> decltype( get_new_opt_helper<Idx, NewVal>
(o, std::make_index_sequence<sizeof...(Fs)>{}) );
您可以使用NewOpts
如下
using new_opt = NewOpts<6u, 82u, myOpts>;
下面是完整编译(C++14,因为使用std::index_sequence
)的例子
#include <cstdint>
#include <utility>
template <std::uint64_t f1 = 0u, std::uint64_t f2 = 0u, std::uint64_t f3 = 0u,
std::uint64_t f4 = 0u, std::uint64_t f5 = 0u, std::uint64_t f6 = 0u,
std::uint64_t f7 = 0u, std::uint64_t f8 = 0u, std::uint64_t f9 = 0u,
std::uint64_t f10 = 0u>
class Options
{ };
template <std::size_t Idx, std::uint64_t NewVal, std::uint64_t ... Fs,
std::size_t ... Is>
constexpr auto get_new_opt_helper (Options<Fs...>,
std::index_sequence<Is...>)
-> std::remove_reference_t<
decltype( std::declval<Options<(Idx == Is ? NewVal : Fs)...>>() )>;
template <std::size_t Idx, std::uint64_t NewVal, std::uint64_t ... Fs>
constexpr auto get_new_opt (Options<Fs...> o)
-> decltype( get_new_opt_helper<Idx, NewVal>
(o, std::make_index_sequence<sizeof...(Fs)>{}) );
template <std::size_t Idx, std::uint64_t NewVal, typename MO>
using NewOpts = decltype(get_new_opt<Idx, NewVal>(std::declval<MO>()));
int main ()
{
using myOpts = Options<51u, 8u, 12u>;
using new_opt = NewOpts<6u, 82u, myOpts>;
using target_opt = Options<51u, 8u, 12u, 0u, 0u, 0u, 82u>;
static_assert( std::is_same<new_opt, target_opt>::value, "!" );
}
如果我使用以下类型:
template<uint64_t f1 = 0, uint64_t f2 = 0, uint64_t f3 = 0, ..., uint64_t f10 = 0>
class Options;
using myOpts = Options<51, 8, 12>;
无论如何我可以做一些等效于这个伪代码的事情吗:
using newOpts = myOpts[6]<82>;
这将保留所有现有的模板参数并将第 7 个设置为 82
。
我提出一个模板using
如下
template <std::size_t Idx, std::uint64_t NewVal, typename MO>
using NewOpts = decltype(get_new_opt<Idx, NewVal>(std::declval<MO>()));
其中 get_new_opts()
和 get_new_opts_helper()
仅声明辅助函数如下
template <std::size_t Idx, std::uint64_t NewVal, std::uint64_t ... Fs,
std::size_t ... Is>
constexpr auto get_new_opt_helper (Options<Fs...>,
std::index_sequence<Is...>)
-> std::remove_reference_t<
decltype( std::declval<Options<(Idx == Is ? NewVal : Fs)...>>() )>;
template <std::size_t Idx, std::uint64_t NewVal, std::uint64_t ... Fs>
constexpr auto get_new_opt (Options<Fs...> o)
-> decltype( get_new_opt_helper<Idx, NewVal>
(o, std::make_index_sequence<sizeof...(Fs)>{}) );
您可以使用NewOpts
如下
using new_opt = NewOpts<6u, 82u, myOpts>;
下面是完整编译(C++14,因为使用std::index_sequence
)的例子
#include <cstdint>
#include <utility>
template <std::uint64_t f1 = 0u, std::uint64_t f2 = 0u, std::uint64_t f3 = 0u,
std::uint64_t f4 = 0u, std::uint64_t f5 = 0u, std::uint64_t f6 = 0u,
std::uint64_t f7 = 0u, std::uint64_t f8 = 0u, std::uint64_t f9 = 0u,
std::uint64_t f10 = 0u>
class Options
{ };
template <std::size_t Idx, std::uint64_t NewVal, std::uint64_t ... Fs,
std::size_t ... Is>
constexpr auto get_new_opt_helper (Options<Fs...>,
std::index_sequence<Is...>)
-> std::remove_reference_t<
decltype( std::declval<Options<(Idx == Is ? NewVal : Fs)...>>() )>;
template <std::size_t Idx, std::uint64_t NewVal, std::uint64_t ... Fs>
constexpr auto get_new_opt (Options<Fs...> o)
-> decltype( get_new_opt_helper<Idx, NewVal>
(o, std::make_index_sequence<sizeof...(Fs)>{}) );
template <std::size_t Idx, std::uint64_t NewVal, typename MO>
using NewOpts = decltype(get_new_opt<Idx, NewVal>(std::declval<MO>()));
int main ()
{
using myOpts = Options<51u, 8u, 12u>;
using new_opt = NewOpts<6u, 82u, myOpts>;
using target_opt = Options<51u, 8u, 12u, 0u, 0u, 0u, 82u>;
static_assert( std::is_same<new_opt, target_opt>::value, "!" );
}