久久久久久久av_日韩在线中文_看一级毛片视频_日本精品二区_成人深夜福利视频_武道仙尊动漫在线观看

為每個可變參數模板參數和數組調用一個函數

Calling a function for each variadic template argument and an array(為每個可變參數模板參數和數組調用一個函數)
本文介紹了為每個可變參數模板參數和數組調用一個函數的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!

問題描述

限時送ChatGPT賬號..

所以我有一些類型 X:

typedef ... X;

和模板函數f:

class <typename T>
void f(X& x_out, const T& arg_in);

然后是一個函數 g:

void g(const X* x_array, size_t x_array_size);

我需要編寫一個可變參數模板函數 h 來做到這一點:

I need to write a variadic template function h that does this:

template<typename... Args>
void h(Args... args)
{
    constexpr size_t nargs = sizeof...(args); // get number of args
    X x_array[nargs]; // create X array of that size

    for (int i = 0; i < nargs; i++) // foreach arg
        f(x_array[i], args[i]); // call f (doesn't work)

    g(x_array, nargs); // call g with x_array
}

它不起作用的原因是因為你不能在運行時像這樣下標.

The reason it doesn't work is because you can't subscript args like that at runtime.

替換h中間部分的最佳技術是什么?

What is the best technique to replace the middle part of h?

獲勝者是 Xeo:

template<class T> X fv(const T& t) { X x; f(x,t); return x; }

template<class... Args>
void h(Args... args)
{
  X x_array[] = { fv(args)... };

  g(x_array, sizeof...(Args));
}

(實際上在我的特定情況下,我可以重寫 f 以按值而不是作為輸出參數返回 x,所以我什至不需要上面的 fv)

(Actually in my specific case I can rewrite f to return x by value rather than as an out parameter, so I don't even need fv above)

推薦答案

你可以重構或包裝 f 以返回一個新的 X 而不是讓它通過,因為這會玩包擴展到手,使功能真正簡潔:

You could refactor or wrap f to return a new X instead of having it passed, since this would play pack expansion into the hand and make the function really concise:

template<class T>
X fw(T const& t){ X x; f(x, t); return x; }

template<class... Args>
void h(Args... args){
  X xs[] = { fw(args)... };
  g(xs, sizeof...(Args));
}

現場示例.

如果您可以將 g 更改為僅接受 std::initializer_list,它會變得更加簡潔:

And if you could change g to just accept an std::initializer_list, it would get even more concise:

template<class... Args>
void h(Args... args){
  g({f(args)...});
}

現場示例.或者(也許更好),您也可以僅提供一個包裝器 g轉發到真正的g:

Live example. Or (maybe better), you could also provide just a wrapper g that forwards to the real g:

void g(X const*, unsigned){}

void g(std::initializer_list<X> const& xs){ g(xs.begin(), xs.size()); }

template<class... Args>
void h(Args... args){
  g({f(args)...});
}

現場示例.
另一種選擇是使用臨時數組:

Live example.
Another option is using a temporary array:

template<class T>
using Alias = T;

template<class T>
T& as_lvalue(T&& v){ return v; }

template<class... Args>
void h(Args... args){
  g(as_lvalue(Alias<X[]>{f(args)...}), sizeof...(Args));
}

現場示例. 請注意,as_lvalue 函數是危險的,數組仍然只存在到完整表達式的結尾(在本例中為 g),所以在使用它時要小心.Alias 是必需的,因為語言語法不允許 X[]{ ... } .

Live example. Note that the as_lvalue function is dangerous, the array still only lives until the end of the full expression (in this case g), so be cautious when using it. The Alias is needed since just X[]{ ... } is not allowed due to the language grammar.

如果這一切都不可能,您將需要遞歸訪問 args 包的所有元素.

If all of that's not possible, you'll need recursion to access all elements of the args pack.

#include <tuple>

template<unsigned> struct uint_{}; // compile-time integer for "iteration"

template<unsigned N, class Tuple>
void h_helper(X (&)[N], Tuple const&, uint_<N>){}

template<unsigned N, class Tuple, unsigned I = 0>
void h_helper(X (&xs)[N], Tuple const& args, uint_<I> = {}){
  f(xs[I], std::get<I>(args));
  h_helper(xs, args, uint_<I+1>());
}

template<typename... Args>
void h(Args... args)
{
    static constexpr unsigned nargs = sizeof...(Args);
    X xs[nargs];

    h_helper(xs, std::tie(args...));

    g(xs, nargs);
}

現場示例.

受 ecatmur 評論的啟發,我采用了索引技巧使其僅通過包擴展和 fg 原樣工作,而無需更改它們.

Inspired by ecatmur's comment, I employed the indices trick to make it work with just pack expansion and with f and g as-is, without altering them.

template<unsigned... Indices>
struct indices{
  using next = indices<Indices..., sizeof...(Indices)>;
};
template<unsigned N>
struct build_indices{
  using type = typename build_indices<N-1>::type::next;
};
template <>
struct build_indices<0>{
  using type = indices<>;
};
template<unsigned N>
using IndicesFor = typename build_indices<N>::type;

template<unsigned N, unsigned... Is, class... Args>
void f_them_all(X (&xs)[N], indices<Is...>, Args... args){
  int unused[] = {(f(xs[Is], args), 1)...};
  (void)unused;
}

template<class... Args>
void h(Args... args){
  static constexpr unsigned nargs = sizeof...(Args);
  X xs[nargs];
  f_them_all(xs, IndicesFor<nargs>(), args...);
  g(xs, nargs);
}

現場示例.

這篇關于為每個可變參數模板參數和數組調用一個函數的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!

【網站聲明】本站部分內容來源于互聯網,旨在幫助大家更快的解決問題,如果有圖片或者內容侵犯了您的權益,請聯系我們刪除處理,感謝您的支持!

相關文檔推薦

Difference between std::reference_wrapper and simple pointer?(std::reference_wrapper 和簡單指針的區別?)
Difference between const. pointer and reference?(常量之間的區別.指針和引用?)
How to access the contents of a vector from a pointer to the vector in C++?(c++ - 如何從指向向量的指針訪問向量的內容?)
Meaning of *amp; and **amp; in C++(*amp; 的含義和**amp;在 C++ 中)
Why can#39;t I do polymorphism with normal variables?(為什么我不能對普通變量進行多態?)
Dereferencing deleted pointers always result in an Access Violation?(取消引用已刪除的指針總是會導致訪問沖突?)
主站蜘蛛池模板: 中文字幕乱码视频32 | 久久精品视频在线免费观看 | 一级亚洲| 91网站视频在线观看 | 色一级 | 日韩成年人视频在线 | 日韩精品久久一区二区三区 | 国产午夜视频 | 婷婷福利视频导航 | 精品国产一区二区三区久久影院 | 99爱在线视频| 成人欧美一区二区三区黑人孕妇 | 日韩一区二区在线免费观看 | 久久夜色精品国产 | 久久久久亚洲 | 亚洲精品一区二区在线观看 | 国产精品777一区二区 | 99视频网站| 日本精品久久 | 毛片com| 国产婷婷综合 | av在线免费网站 | 国产精品免费在线 | 欧美a级成人淫片免费看 | 亚洲精品一区二区三区中文字幕 | 国产99久久精品一区二区永久免费 | 一区二区三区免费 | 成年人免费网站 | 久久黄色网 | 久久久久国产一区二区三区四区 | 中文字幕免费在线 | 羞羞视频在线观看 | 亚洲国产精品91 | 999精品在线 | 精品亚洲一区二区三区 | 性欧美hd | 久久久精品视 | 久久久久久99 | 狠狠狠色丁香婷婷综合久久五月 | 久久精品视频免费观看 | 少妇一区在线观看 |