2015-11-23 6 views
8
#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“ необходимо?

+2

параметров пакета допускается в основном, где разделенный запятыми список допускается. Существует фиксированное количество контекстов: списки параметров функций, списки параметров шаблонов, инициализаторы и т. Д. Выражение не является допустимым контекстом. Оператор запятой не делает список, разделенный запятыми. –

+0

Если SO просит вас добавить более подробную информацию, добавьте более подробную информацию. Не фиктивный текст. Благодарю. –

ответ

12

По существу, расширение параметр обновления E...производит листE1, E2, [...], EN, один E для каждого элемента в пакете. Эта синтаксическая конструкция действительна только в тех местах, где списки грамматически правильны, например, в вызовах функций, списках инициализаторов и т. Д. Выражение, содержащее несколько операторов запятой, не учитывается.

Я считаю, что с fold expressions (N4295: Folding expressions (Andrew Sutton, Richard Smith)), вы будете иметь возможность просто написать:

(print(a), ...); 

В этом выражении

  • print(a) является выражением с нераскрытым параметрами пакетом,
  • , является оператором и
  • ... desi сглаживает разложение вправо.

Результатом всего выражения является то, что (print(a), ...) будет преобразован в

print(a1) , (print(a2), (print(a3), print(a4))) // (assuming four elements). 
+1

теперь вы задали мне вопрос, почему это так, поскольку 'foo(), foo();' является допустимым выражением. –

+0

@RichardHodges это допустимое выражение, но это не список * в соответствии с грамматикой. – TartanLlama

+1

Я понимаю это. Мне интересно, почему расширение пакета было ограничено списками и не разрешено для операторов. –

5

пакета обновления расширений может произойти только в контексте расширения пакета. Это, по существу, является:

  • приготовился инициализация
  • инициализатор списки
  • агрегатной инициализация
  • вызовов функций
  • инициализацию массива

Из них легче использовать в вашем случае будет правильным Последнее обновление:

#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; 
} 
расширение

Demo

+0

@LightnessRacesinOrbit Я не понимаю –

+3

Я смеюсь над C++. То, что этот синтаксис является «самым простым» способом сделать эту простую вещь, смехотворно. –

Смежные вопросы