Следующее не удается скомпилировать как на gcc, так и на clang
#include <type_traits>
int foo();
int main()
{
using R = std::result_of_t<decltype(foo)()>; // error
}
Ошибка обоих компиляторов связана с незаконностью объявления функции, возвращающей функцию. Но я не объявляю такую функцию — я просто пытаюсь написать ее тип — поскольку это то, что result_of
надеется. Это действительно все еще плохо сформировано?
Вы передаете тип-идентификатор, который определен в [Dcl.name] как
[…] Синтаксически объявление для переменной или функции этого типа, в которой отсутствует имя объекта. […] Можно однозначно определить местоположение в абстрактно-описатель где идентификатор появится если конструкция была декларатором в декларации. Именованный тип тогда совпадает с типом
гипотетический идентификатор.
Чтобы гипотетический идентификатор имел некоторый тип, гипотетическое объявление должно быть правильно сформировано. Но это не согласно [Dcl.fct] / 10. Следовательно, программа плохо сформирована (и сообщения об ошибках компилятора на самом деле понятны). Этот случай также более непосредственно [Temp.deduct] / (8,10), подразумевая, что это (SFINAE-friendly) ошибка.
На самом деле, просто подразумевает использование недопустимого типа, чтобы сделать программу плохо сформированной. Например. создание указателя типа на функцию, возвращающую функцию, некорректно:
using f = int();
using t = f(*)();
Так же и следующее:
struct A {virtual void f() = 0;};
using t = A(*)();
(Clang не должен принимать это. C.f. GCC bug 17232Интересная дискуссия).
Других решений пока нет …