例如,假設我有以下內容:
template<typename ...FunctionTypes>
static void MainFunction(FunctionTypes... functions)
{
constexpr Uint32_t NumFunctions= sizeof...(FunctionTypes);
std::array<double, NumFunctions> myArray;
double arg1 = 4.2;
int arg2= 9;
for_each_tuple(myArray, FigureOutThisPart(myFunctions, arg1, arg2)...);
}
Wherefor_each_tuple需要一個大小的元組或陣列N以及N應用于每個元組條目的函式。這部分實施起來很棘手,但有效!它是這樣定義的:
namespace detail {
template <typename Tuple, std::size_t ...Indices, typename ...FunctionTypes>
constexpr void for_each_tuple_impl(Tuple&& tuple, std::index_sequence<Indices...>, FunctionTypes&&... functionsIn) {
std::tuple<FunctionTypes...> functions = std::tie(functionsIn...);
using swallow = int[];
(void)swallow{
1, // Make sure array has at least one element
(std::get<Indices>(functions)(std::get<Indices>(std::forward<Tuple>(tuple))), void(), int{})...
};
}
}
template <typename Tuple, typename ...Functions>
void for_each_tuple(Tuple&& tuple, Functions&&... f) {
constexpr std::size_t N = std::tuple_size<std::remove_reference_t<Tuple>>::value;
static_assert(N == sizeof...(Functions), "Need one function per tuple entry");
detail::for_each_tuple_impl(
std::forward<Tuple>(tuple),
std::make_index_sequence<N>{},
std::forward<Functions>(f)...);
}
這個想法是我有一套myFunctions,每一套都在不同的條目上運行myArray。中的每個函式myFunctions都將arg1,arg2和當前陣列條目作為引數。
我的目標是能夠傳遞arg1并arg2進入每個,myFunctions以便可以在當前陣列條目的操作中使用這些值。有沒有一種理智的方法可以做到這一點?理想情況下,我希望解決方案是 constexpr,這樣所有事情都可以在編譯時得到解決。
uj5u.com熱心網友回復:
我認為這樣的事情可以作業:
#include <array>
#include <functional>
template<typename ...FunctionTypes>
constexpr void MainFunction(FunctionTypes... functions)
{
constexpr auto NumFunctions= sizeof...(FunctionTypes);
std::array<double, NumFunctions> myArray{};//Zero-init for now.
double arg1 = 4.2;
int arg2= 9;
std::size_t i=0;
(std::invoke(functions, arg1,arg2, myArray[i ]),...);
}
#include <iostream>
void foo(double a1, int a2, int a){
std::cout<<"Called foo("<<a1<<','<<a2<<','<<a<<")\n";
}
int main()
{
MainFunction(foo,foo);
return 0;
}
它需要 C 17 的折疊運算式和逗號的序列點。
它可以在編譯時評估:
constexpr void bar(double a1, int a2, int a){
}
int main()
{
constexpr auto x = (MainFunction(bar,bar),1); // Force compile-time evaluation.
return 0;
}
uj5u.com熱心網友回復:
我會在一開始就用函子制作一個元組,并將元組的一個元素與陣列的相應元素匹配:
template<std::size_t I, typename E, typename ...F, typename ...Args>
constexpr void apply(const std::array<E, sizeof...(F)>& elements,
const std::tuple<F...>& functions,
Args... args) {
std::get<I>(functions)(std::get<I>(elements), args...);
}
template<std::size_t ...I, typename E, typename ...F, typename ...Args>
constexpr void for_each(std::index_sequence<I...>,
const std::array<E, sizeof...(I)>& elements,
const std::tuple<F...>& functions,
Args... args) {
(apply<I>(elements, functions, args...),...);
}
template<typename ...F>
constexpr static void MainFunction(F... functors)
{
constexpr std::size_t size = sizeof...(F);
constexpr std::array<double, size> elements{};
constexpr double arg1 = 4.2;
constexpr int arg2 = 9;
for_each(std::make_index_sequence<size>(),
elements,
std::forward_as_tuple(functors...),
arg1, arg2);
}
客戶端代碼將如下所示:
void function(double val, double arg1, int arg2) {
std::cout << arg1 arg2 8 * val << std::endl;
}
int main() {
MainFunction(function, [](double val, double arg1, double arg2) {
std::cout << val / arg1 arg2 << std::endl;
});
return 0;
}
只要引數函式是constexpr,實作也是constexpr:
template<typename ...F>
constexpr static auto MainFunction(F... functors) { ... return elements; }
constexpr void function(double val, double arg1, int arg2) { ... }
int main() {
// Retrieves the constexpr elements array from the function
constexpr auto val = MainFunction(function, [](double, double, int){ ... });
}
uj5u.com熱心網友回復:
您可以使用std::bind_front來構造一個具有占位符引數的函式,這是一個更接近您最初預期的解決方案。然而,這有一個不能在constexpr背景關系中運行的缺點:
template <std::size_t N, typename T, typename... Functions>
auto for_each_tuple(std::array<T, N> const& array, Functions... functions) {
auto index = 0uz;
(std::invoke(functions, array[index ]), ...);
}
template<typename ...FunctionTypes>
static void MainFunction(FunctionTypes... functions)
{
constexpr std::uint32_t NumFunctions= sizeof...(FunctionTypes);
std::array<double, NumFunctions> myArray{};
double arg1 = 4.2;
int arg2= 9;
for_each_tuple(myArray, std::bind_front(functions, arg1, arg2)...);
}
auto main() -> int {
auto print_thrice = [](double d1, int i2, double arr) {
std::cout << d1 << ' ' << i2 << ' ' << arr << '\n';
};
MainFunction(print_thrice, print_thrice, print_thrice);
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/506771.html
