[英]Parameter packs not expanded with '...'
我有這個代碼:
#include <iostream>
using namespace std;
int print(int i)
{
cout << endl << i;
}
template<typename ...Args>
inline void pass(Args&&...args)
{
}
template<typename ...args>
inline void expand(args&&... a)
{
print(a) ...; //this doesn't expand
//pass( print(a)... ); this works
}
int main() {
expand(1,2,3,4);
return 0;
}
它拋出一個錯誤:
In function 'void expand(args&& ...)':
error: expected ';' before '...' token
print(a) ...;
^
parameter packs not expanded with '...':
print(a) ...;
^
為什么需要使用pass()
函數?
本質上,擴展參數包E...
會生成一個列表E1, E2, [...], EN
,包中的每個元素都有一個E
此句法結構僅在列表語法正確的地方有效,例如在函數調用、初始值設定項列表等中。包含多個逗號運算符的表達式不計算在內。
我相信使用折疊表達式( N4295:折疊表達式(Andrew Sutton,Richard Smith) ),您將能夠簡單地編寫:
(print(a), ...);
在這個表達式中,
print(a)
是一個帶有未擴展參數包的表達式,,
是運算符和...
指定正確的折疊擴展。 整個表達式的結果是(print(a), ...)
將轉化為
print(a1) , (print(a2), (print(a3), print(a4))) // (assuming four elements).
包擴展只能發生在包擴展上下文中。 這些基本上是:
其中最容易在您的情況下使用的是最后一個:
#include <iostream>
using namespace std;
int print(int i)
{
cout<<endl<<i;
return 0;
}
template<typename ...args>
inline void expand(args&&... a)
{
using expander = int[];
(void)expander{0, ((void)print(a), 0)...};
}
int main()
{
expand(1,2,3,4);
return 0;
}
這個也有效:
#include <iostream>
void print() {}
template<typename T, typename ... Types>
void print (T firstArg, Types ... args) {
std::cout << firstArg << "\n";
print(args...);
}
int main() {
print("Hello",1337,42.44,"World");
}
您可能需要考慮以下 C++ 11 代碼:
#include <iostream>
template<typename T, typename... Ts>
auto printf3(T value, Ts... args) {
std::cout << value << std::endl;
(void) std::initializer_list<T>{([&args] {
std::cout << args << std::endl;
}(), value)...};
}
使用C++17
和 fold 表達式,上面的代碼可以簡化如下:
#include <iostream>
template<typename ...args>
inline void print(args&&... a) {
((std::cout << a << std::endl), ...);
}
int main() {
print(1,2,3,4);
return 0;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.