我正在嘗試為我的 std::function 分配一個 lambda,其中包含對引數包中指定的每種型別的 1 個 Test 呼叫,有人知道該怎么做嗎?
template<typename T>
void Test() {
}
template<typename ... Ts>
void Expand() {
std::function<void(void)> func = [Ts] {
for (const auto& p : { Ts... })
Test<Ts...>();
};
}
int main(int argc, char** argv) {
Expand<int, char>();
}
我正在嘗試將其擴展到...
Test<int>();
Test<char>();
uj5u.com熱心網友回復:
template<typename ... Ts>
Ts這里代表型別。模板引數是型別。
[Ts] {
// ...
}
lambda 的捕獲捕獲值和離散物件而不是型別。沒有捕獲types之類的東西。
for (const auto& p : { Ts... })
范圍迭代迭代某個容器中的值。花括號初始化串列也是串列值,而不是型別。
這里的主要混淆是 C 中型別和值之間的混淆。
如果意圖是生成“對引數包中指定的每種型別的 Test 呼叫”,那么最簡單的解決方案是使用 C 17 的折疊運算式:
template<typename ... Ts>
void Expand() {
std::function<void(void)> func = [] {
( Test<Ts>(), ...);
};
}
您將問題標記為 C 11,但在 2022 年,您的編譯器很可能也支持 C 17。
萬一您僅限于 C 11,可以將輔助一次性 void 函式用作拐杖:
template<typename ...Args>
void ignore_me(Args && ...args)
{
}
template<typename ... Ts>
void Expand() {
std::function<void(void)> func = [] {
ignore_me( (Test<Ts>, 0)...);
};
}
uj5u.com熱心網友回復:
您標記了 C 11,因此如果您在 C 11 中擁有最新的標準版本,則需要遞回執行。
template <typename... Ts>
struct ExpandHelper;
template <>
struct ExpandHelper<> {
void operator()() {
// Empty body.
}
}
template <typename T, typename... Ts>
struct ExpandHelper<T, Ts...> {
void operator()() {
Test<T>();
ExpandHelper<Ts...> rest;
rest();
}
}
template <typename... Ts>
void expand() {
std::function<void(void)> func = [] {
ExpandHelper<Ts...> helper;
helper();
};
}
但是,如果您可以訪問 C 17,則可以使用帶有逗號運算子的折疊運算式,并且結果要短得多。
template <typename... Ts>
void expand() {
std::function<void(void)> func = [] {
(Test<Ts>, ...)
};
}
uj5u.com熱心網友回復:
template<typename T>
void Test() {
using namespace boost::typeindex;
std::cout << stl_type_index(typeid(T)).pretty_name() << std::endl;
}
template<typename...Ts>
void Expand() {
(Test<Ts>(), ...);
}
int main(int argc, char** argv) {
Expand<int, char>();
}
輸出...
int
char
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/513371.html
標籤:C c 11参数包
