Почему и как дополнительные круглые скобки меняют тип выражения в С++ (С++ 11)?

В каких обстоятельствах дополнительные скобки для группировки ломают вещи на С++ (специально для С++ 11)? По причинам, которые здесь неактуальны, в какой-то момент я оказался с выражением, которое содержало лишний набор ненужных парсеров вокруг него, и я обнаружил, что функция typeinfo is_same С++ 11 определяла ее как другую тип, чем тот же код без круглых скобок. Вот пример сдержанного поведения:

#include <iostream>
using namespace std;

int main()
{
  string s = "foo";
  cout << std::is_same<decltype(s), decltype(string("foo"))>::value;
  cout << std::is_same<decltype(s), decltype((s))>::value;
  cout << std::is_same<decltype((s)), decltype(string("foo"))>::value;
  cout << std::is_same<decltype((s)+"x"), decltype(string("foo")+"x")>::value;

  return 0;
}

Этот код печатает "1001", что, по-видимому, указывает на то, что дополнительные парсеры в средних двух линиях вызывают выражение другого типа, но использование этого выражения в скобках в более крупном выражении делает его снова одним и тем же. С другой стороны, если я использую typeid для получения имени для типа, typeid(s) и typeid((s)), похоже, создают одно и то же.

Теперь я работал над непосредственной проблемой, но я до сих пор не понимаю, почему это происходит в первую очередь; поиск вокруг "двойных скобок С++" и т.д., похоже, не приводит к чему-либо значимому (в основном страницы о перегрузке операторов и расширениях компилятора, которые активируются только после определенного ключевого слова).

Итак: что, черт возьми, происходит здесь? Почему тип s отличается от типа (s)?

Ответы

Ответ 1

decltype рассматривает свои аргументы по-разному в зависимости от дополнительных круглых скобок.

Вторая пара круглых скобок делает это первичным выражением (но не является явным выражением или доступом к классу), поэтому специальное правило не применяется.

Вот обсуждение: Значение круглых скобок в decltype ((c))?