Почему и как дополнительные круглые скобки меняют тип выражения в С++ (С++ 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))?