Должна ли decltype Trigger компиляция ее аргумента?

Поэтому я недоумеваю, как это работает. Дано:

template <typename T>
int foo(T t) { t.foo(); }

Кажется, что этот вызов должен завершиться неудачно:

decltype(foo(int{ 13 })) fail = 42;

cout << fail << endl;

Вместо он просто печатает:

42

Он работает таким образом на всех компиляторах, к которым у меня есть доступ. Это правильное поведение? Я запрашиваю цитату из стандарта С++.

Ответы

Ответ 1

В [dcl.spec]:

Для выражения e тип, обозначенный как decltype (e), определяется как следующим образом:

если e - это unparenthesized id-expression, обозначающее lvalue или ссылку, введенную из идентификатора-списка разложения объявление, decltype (e) является ссылочным типом, указанным в спецификация объявления декомпозиции ([dcl.decomp]);

в противном случае, если e - это несферизованное id-выражение или unparenthesized доступ к члену класса ([expr.ref]), decltype (e) - это тип объекта, названного e. Если такого субъекта нет или если e называет набор перегруженных функций, программа плохо сформирована;

в противном случае, если e является значением x, decltype (e) является T & &, где T - тип e;

в противном случае, если e является lvalue, decltype (e) является T &, где T - тип e;

иначе, decltype (e) - тип e.

Операндом спецификатора decltype является необоснованный операнд(Пункт [expr]).

(Акцент мой)

Итак, ваш foo(int{ 13 }) никогда не оценивается.

Ответ 2

Выражения в decltype определяются стандартом, чтобы его не оценивали, они анализируются только для получения типа выражения.