我必須遵循以下程式:
#include <iostream>
#define max_dim 100
template<unsigned IDim>
struct Node{};
int main() {
uint x;
std::cout << "Input dimension: ";
std::cin >> x;
if(x < max_dim){
Node<x> node;
}else{
std::cout << "False Input.";
}
}
它不會編譯,因為運算式Node<x> node需要x是一個常量值,而事實并非如此。因為我的可能性有限x(受限制max_dim)我當然可以只使用 if 條件或 switch 陳述句,但這會導致大量冗余代碼(特別是因為我正在做一堆每個節點的操作)。
我真的無法改變節點的結構。
有沒有更優雅的方法來實作這一目標?
uj5u.com熱心網友回復:
std::index_sequence 可能有幫助。
然后有幾種從運行時值中選擇編譯代碼的方法(遞回、具有線性檢查索引的折疊運算式),這里使用陣列(O(1) 訪問但在記憶體中是線性的)。
template <std::size_t I>
void f(/*..*/)
{
Node<I> node;
// Your code...
}
template <std::size_t... Is>
constexpr std::array<void(*)(/*..*/), sizeof...(Is)>
make_funcs(std::index_sequence<Is...>)
{
return {{ &f<Is>... }};
}
template <std::size_t N>
constexpr std::array<void(*)(/*..*/), N> make_funcs()
{
return make_funcs(std::make_index_sequence<N>());
}
接著
int main() {
std::cout << "Input dimension: ";
uint x;
std::cin >> x;
if (x < max_dim) {
constexpr auto funcs = make_funcs<max_dim>();
funcs[x](/*..*/);
} else {
std::cout << "False Input.";
}
}
uj5u.com熱心網友回復:
使用輔助函式的 C 17 解決方案,假設Node<x>背景關系不需要回傳值:
#include<utility>
template<typename T, auto... I>
void f(std::integer_sequence<T, I...>, T x) {
((x == I && ([]{
Node<I> node;
// do something with node
}(), true)) || ... || (std::cout << "False Input."));
}
// in main
f(std::make_integer_sequence<decltype(x), max_dim>{}, x);
可以僅使用 lambdas 而不是輔助函式來撰寫解決方案,但它看起來更不清晰。這里的重要概念是折疊運算式和std::integer_sequence將模板引數包引入函式的方法。的&&/ ||/(..., true)結構本質上只是一個if/else if寫為一個單一的表達依賴于邏輯運算子的短路行為構建體。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/399080.html
上一篇:使用類模板節點需要模板引數C
