ein*_*ica 5 c++ templates idiomatic template-specialization template-meta-programming
假设我们有诸如此类的功能
template <typename T, unsigned N> void foo();
Run Code Online (Sandbox Code Playgroud)
为简单起见,假设我们知道只有(常量)值N_1
,N_2
...... N_k
有效N
.
现在,假设我想将编译时参数设置为运行时参数,使用foo()
黑盒,即实现:
template <typename T> void foo(unsigned n);
Run Code Online (Sandbox Code Playgroud)
通过foo<,>()
打电话.我应该怎么做呢?显然,我可以写:
template <typename T> void foo(unsigned n) {
switch(n) {
case N_1 : foo<T, N_1>(); break;
case N_2 : foo<T, N_2>(); break;
// etc. etc.
case N_k : foo<T, N_k>(); break;
}
}
Run Code Online (Sandbox Code Playgroud)
......但这让我感到很脏.我想,我可以使用MAP()元宏来生成这些k行; 但我可以做更好的事情,而不是那么做宏观的事情吗?是否有可能编写类似上面的通用,并适用于每个可变参数模板和固定值的常量值?
笔记:
你可以创建一个函数指针表:
using F = void(*)();
template <class T, class >
struct Table;
template <class T, size_t... Is>
struct Table<T, std::index_sequence<Is...> > {
static constexpr F fns[] = {
foo<T, Is>...
};
};
template <class T, size_t... Is>
constexpr F Table<T, std::index_sequence<Is...> >::fns[sizeof...(Is)];
Run Code Online (Sandbox Code Playgroud)
然后只需调用你想要的那个:
template <class T, size_t N>
struct MakeTable : Table<T, std::make_index_sequence<N>> { };
template <typename T>
void foo(unsigned n) {
MakeTable<T, MaxN>::fns[n]();
}
Run Code Online (Sandbox Code Playgroud)
如果N_k
s不连续,那么我们可以使用lambda进行内联参数解包:
template <class T>
void foo(unsigned n) {
using seq = std::index_sequence<N_1, N_2, ..., N_k>;
indexer(seq)([n](auto i){
if (n == i) {
f<T, i>();
}
});
}
Run Code Online (Sandbox Code Playgroud)
如果上面的速度太慢,那么我想只需手动构建一个std::unordered_map<unsigned, void(*)()>
或者其他东西.
归档时间: |
|
查看次数: |
87 次 |
最近记录: |