Что делает 'void()' в 'auto f(params) -> decltype(, void())'?

Я нашел код здесь, который выглядел примерно так:

auto f(T& t, size_t n) -> decltype(t.reserve(n), void()) { .. }

Во всей документации, которую я читал, мне сказали, что decltype подписано как:

decltype( entity )

or

decltype( expression )

И нигде нет второго аргумента. По крайней мере, это указано в cppreference. Является ли это вторым аргументом для decltype? И если да, то что он делает?


person template boy    schedule 22.12.2012    source источник


Ответы (1)


Поскольку это выражение, запятая является просто оператором запятой (что означает, что тип является типом правой стороны: void), а не другим аргументом.

Этот код использует SFINAE — он включен, если существует t.reserve(n), но он хочет сохранить возвращаемый тип как void.

person Pubby    schedule 22.12.2012
comment
я бы никогда не догадался. Спасибо. - person template boy; 22.12.2012
comment
@templateboy: оператор запятой всегда появляется в самых неожиданных местах;) - person Matthieu M.; 22.12.2012
comment
OMG, нам очень нужны языковые конструкции, чтобы не писать такие хакерские трюки! О__О;;; - person Klaim; 22.12.2012
comment
@Klaim: Это намного лучше, чем SFINAE, который обычно был до C ++ 11. - person Ben Voigt; 22.12.2012
comment
@BenVoigt Я согласен, но это более неясно! - person Klaim; 22.12.2012
comment
@Waleed Khan Будут ли концепты C++14 заканчиваться SFINAE? - person Alessandro Stamatto; 26.02.2013
comment
Просто любопытно, возможно ли использование самого void() вообще только потому, что мы находимся в неоцененном контексте - person abigagli; 18.08.2014
comment
@abigagli Да, void - это неполный тип, поэтому вы не можете вызывать его конструктор где-либо вне неопределенного контекста, такого как decltype() или sizeof(). - person 0x499602D2; 30.10.2014
comment
@ 0x499602D2 Неправда. Вы можете использовать void() везде, где разрешено значение void prvalue (конечно, их не очень много...) - person T.C.; 03.03.2015