Ответ 1
Интересный вопрос.
Исправляя мою первую интерпретацию, мне кажется, что g++ и clang++ правы и что MSVC ошибочен.
Я предполагаю это, потому что в проекте n4659 для С++ 17 (извините: у меня нет доступа к окончательной версии). Я вижу правила выражения (A.4), в которых оператор деления участвует в "мультипликативном -expression" следующим образом
мультипликативное выражение/pm-выражение
"Мультипликативное выражение" может быть также "pm-выражением", которое может быть "выражением-выражением", которое может быть "унарным выражением", которое может быть "постфиксным выражением", которое может быть "первичное выражение", которое может быть "сглаживанием"
Таким образом, правило можно увидеть как
fold-expression/pm-expression
Итак, если я не ошибаюсь, "fold-expression" следует оценивать как целое до применения деления.
Моя первая интерпретация (MSVC right, g++ и clang++ неправильная) была основана на поспешной лекции 17.5.3
В результате создания выражения сложения получается:
(9.1) ((E1 op E2) op ···) op EN для унарной левой складки
и 8.1.6
Выражение в форме (... op e), где op - оператор сгиба, называется унарной левой складкой.
Поэтому я предположил, что
return (... + values) / static_cast<double>(sizeof...(Ts));
должен быть создан
return ((v1 + v2) + ... ) + vn / static_cast<double>(sizeof...(Ts));
В любом случае... правый MSVC или нет... чтобы быть уверенным, что вы хотите
return (1 + 3) / 2.0;
Я предлагаю вам добавить еще пару круглых скобок.