簡體   English   中英

未使用“...”擴展的參數包

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM