Создают ли круглые скобки не выводимый контекст?

#c #language-lawyer #template-argument-deduction

Вопрос:

temp.вычет.тип#17 указывает, что

Если в объявлении шаблона функции с параметром шаблона, не относящимся к типу, параметр шаблона, не относящийся к типу, используется в подвыражении в списке параметров функции, выражение является не выводимым контекстом, как указано выше.

что означает для следующего заявления о f

 template<int> struct S {};

template<int i> void f(S<i   1>) {}
 

вызов f(S<42>{}) отклонен.

Однако, если декларация f изменена на

 template<int i> void f(S<(i)>) {}
 

только Clang отклоняет вызов с той же ошибкой, что и раньше.

Итак, добавление круглых скобок вокруг i делает его не выводимым контекстом, потому i что это подвыражение (i) ?

Ответ №1:

Подвыражения определяются относительно непосредственных подвыражений:

Подвыражение выражения E является непосредственным подвыражением E или подвыражением непосредственного подвыражения E.

И непосредственные подвыражения частично определяются как:

Непосредственными подвыражениями выражения E являются

  • составные выражения операндов E ([expr.prop]),

Есть и другие возможности, но они, очевидно, не применимы к случаю (N) . Таким образом, вопрос в том, является ли N операндом выражения в скобках.

Ну, не в соответствии с [expr.prim.paren]/1:

Заключенное в скобки выражение (E) является основным выражением, тип, значение и категория значения которого идентичны выражениям E. Заключенное в скобки выражение может использоваться в тех же контекстах, что и те, в которых может использоваться E, и с тем же значением, если не указано иное.

Курсив добавлен. Кажется очевидным , что in (N) , N не является операндом, поэтому он не является непосредственным подвыражением и, следовательно N , не является подвыражением.

Поскольку в [temp.deduct.type]/17 нет ничего, что «указывало бы на иное», кажется очевидным, что (N) и N может использоваться идентично.

Комментарии:

1. Да, в этом есть смысл. Тогда это, похоже, ошибка с лязгом.

2. Хм, глядя, есть ли сообщение об ошибке против Clang, я нашел этот комментарий , первое предложение которого указывает на то, что круглые скобки имеют значение.

3. @cigien: Они могут указывать все, что им нравится , но они не указали, где стандарт говорит N , что это подвыражение (N) , и я указал на все места, где это определенно не сказано.

4. Да, это правда. Я подожду, чтобы посмотреть, есть ли какое нибудь место, где говорится, что () это имеет значение.

5. @cigien: Это имеет большое decltype значение .