При каких обстоятельствах дополнительные группирующие скобки нарушают работу C++ (в частности, C++11)? По причинам, которые здесь не имеют значения, в какой-то момент я столкнулся с выражением, вокруг которого был дополнительный, ненужный набор скобок, и я обнаружил, что функция typeinfo C++11 is_same
определяет, что это другой тип, чем тот же код без скобок. Вот упрощённый пример несколько непонятного поведения:
#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)
?
decltype
, которое применяется, если выражение внутри скобокdecltype
является выражением-идентификатором или доступом-членом-класса. Добавление второй пары скобок делает его основным-выражением (но само не является выражением-идентификатором или доступом-членом-класса), поэтому специальное правило не применяется. См., например, stackoverflow.com/q/14115744/420683 или stackoverflow.com/q/3097779/420683 - person dyp   schedule 03.02.2014foo((1, 2));
имеет другое значение, чемfoo(1, 2);
. Это вопрос вообще про скобки или проdecltype
? - person dyp   schedule 03.02.2014&
:struct foo { int m; void bar() { auto x = &foo::bar; auto y = &(foo::bar); } };
Здесьx
относится к типуint (foo::*)
, тогда какy
относится к типуint*
. Но это не относится к С++ 11. - person dyp   schedule 03.02.2014foo::m
, а неfoo::bar
. - person   schedule 03.02.2014decltype(s)
даетstring
, аdecltype((s))
становитсяstring &
. - person NonNumeric   schedule 03.02.2014foo(1,2)
? Или вы имели в виду(foo)(1,2)
, отключающий ADL? - person TemplateRex   schedule 03.02.2014foo((1,2))
— это вызов функции только с одним выражением аргумента, а именно(1,2)
— это один аргумент со значением2
. И отключение ADL — еще один хороший пример, когда скобки имеют значение :) - person dyp   schedule 03.02.2014