Задать вопрос
@JustMoose
Программист. Радиолюбитель. Прокрастинатор ;)

Какой приоритет операций, разворачивающихся из fold-expression?

Всем привет!
Пытаюсь освоить variadic templates, в процессе наткнулся на странное.
Кусок кода:
#include <iostream>

using namespace std;

void variprint() {}

template<class... Args>
void variprint(Args... args) {
  //cout << "sizeof: " << sizeof...(args) << endl;
  cout << (args << ...) << endl;
}

int main() {
  variprint();
  variprint("test");
  variprint(1, 2);

  return 0;
}


Ожидаю, что увижу на выходе:
test
1 2


Запускаю, и вижу:
test
4


Интуитивно догадываюсь, что что-то не так с приоритетами/порядком выполнения операций, и 1 << 2 превратилось в 4.
Окей, запускаю clang с ключиками для промежуточного вывода шаблонов:
clang.exe -std=c++17 -Xclang -ast-print -fsyntax-only my_file.cpp


Лезу в файл и вижу....
void variprint() {
}
template <class ...Args> void variprint(Args ...args) {
    cout << "sizeof: " << sizeof...(args) << endl;
    cout << (args << ...) << endl;
}
template<> void variprint<<>>()template<> void variprint<<const char *>>(const char *args) {
    cout << "sizeof: " << sizeof...(args) << endl;
    cout << args << endl;
}
template<> void variprint<<int, int>>(int args, int args) {
    cout << "sizeof: " << sizeof...(args) << endl;
    cout << args << args << endl;
}


То есть, никаких скобок там в принципе нет, args сразу пишутся в cout.
Вопрос: почему ж в результате оно себя ведёт так, как будто скобки есть??

ЗЫ: на всякий случай попробовал gcc. Результат точно такой же (то есть, на выходе печатает 4, распечатку темплейтов пока не смотрел).

UPD: ХА! А вот https://cppinsights.io/ показывает действительно нормальные темплейты! Со скобками!
  • Вопрос задан
  • 50 просмотров
Подписаться 1 Средний Комментировать
Решения вопроса 1
jcmvbkbc
@jcmvbkbc
"I'm here to consult you" © Dogbert
Согласно eel.is/c++draft/expr.prim.fold#nt:fold-operator и eel.is/c++draft/temp.variadic#14 чтобы получить то что ты хотел (и что стандарт называет термином "binary left fold") вместо cout << (args << ...) << endl; надо было написать (cout << ... << args) << endl;

почему ж в результате оно себя ведёт так, как будто скобки есть??

Потому что у тебя получился binary right fold.

Какой приоритет операций, разворачивающихся из fold-expression?

Поскольку операция одна и та же, приоритет одинаковый. Свойство о котором ты говоришь называется "ассоциативность". binary right fold ассоциирует подвыражения справа налево, binary left -- слева направо.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы