我想寫這樣的事情:迭代與constexpr
template<int i> void f() {}
for (constexpr int i : {1,2,3})
{
f<i>();
}
是否有可能重複上constexpr?
謝謝
我想寫這樣的事情:迭代與constexpr
template<int i> void f() {}
for (constexpr int i : {1,2,3})
{
f<i>();
}
是否有可能重複上constexpr?
謝謝
正如你可能知道,你不能做類似的:
for (constexpr int i : {1,2,3})
{
f<i>();
}
因爲,如果i
是從1到3的循環變化,那麼它是一個可變和 不是編譯時不變。並且變量不能是模板參數, 與f<i>
中一樣:只有編譯時常量可以是模板參數。
在C++ 11以後,由於variadic templates, 可以有效迭代編譯時的arbitary序列通過使用接受的模板參數的合適的任意序列 模板函數的編譯時遞歸常數 。
這將幾乎意味着什麼給你,如果你已經不知道該怎麼做。 這裏是一個C++ 11例如,你想要表達什麼:
#include <type_traits>
#include <iostream>
template<int i> void f()
{
std::cout << i << '\n';
}
// This overload is chosen when there is only 1 template argument.
template<int First, int ...Rest>
typename std::enable_if<sizeof...(Rest) == 0>::type
for_each_f()
{
f<First>();
}
// This overload is chosen when there is > 1 template argument.
template<int First, int ...Rest>
typename std::enable_if<sizeof...(Rest) != 0>::type
for_each_f()
{
f<First>();
for_each_f<Rest...>();
}
int main()
{
for_each_f<2,3,5,7,11>();
return 0;
}
另外可變參數模板,這種技術依賴於非常重要的C++元編程的SFINAE 原則,在std::enable_if
, 這是標準C++庫提供的利用SFINAE的工具。
101010的答案演示了C++ 14中提供的更復雜,更強大的 解決方案(如果您編寫一些輔助樣板文件,可以輕鬆實現C++ 11 )。
不,您不能在編譯時使用for循環進行迭代。 C++中的for控制結構用於運行時控制流。
但是,您可以使用其他編譯時設施。例如在C++ 14中,您可以通過以下方式實現您想要的功能:
定義將調用您的函數的模板包裝類。
template<int i> struct wrapper { void operator()() const { f<i>(); } };
使用std::index_sequence生成編譯時間指數。
template<template<int> class W, std::size_t... I> void caller_impl(std::index_sequence<I...>) { int t[] = { 0, ((void)W<I>()(), 1)... }; (void) t; } template<template<int> class W, std::size_t N, typename Indices = std::make_index_sequence<N>> void call_times() { caller_impl<W>(Indices()); }
然後調用作爲
int main() { call_times<wrapper, 42>(); }
如果C++ 14是不是一種選擇,你可以看看here你如何實現你的自我std::index_sequence
。
什麼是'(void)t'? –
@DeanSeo抑制未使用變量的編譯器警告。 – 101010
如果你有C++ 17,那麼'caller_impl'函數體可以是'(W ()(),...);'更容易理解。 –
TBH我更喜歡這種方法。 'int t []'(C++的錯誤,而不是101010's)的初始化過程中有很多可怕的駭人聽聞的事情,在我選擇沿着這條路線前,我將不得不給予大量的錢! –
如果您將模板簽名更改爲template,則可以將'enable_if's除去for_each_f();'和template for_each_f();'template ' –