Подтвердить что ты не робот

Почему этот код компилируется с помощью gcc, но не с clang

Этот код отлично работает с gcc/g++ и msvc, но не с clang. Он продолжает жаловаться на то, что не найдено подходящей функции для журнала, что происходит?

#include <iostream>

template <typename Function, typename... Args>
auto Call(Function func, Args&&... args) -> typename std::result_of<Function&(Args&&...)>::type
{
    return func(std::forward<Args>(args)...);
}

template <typename T, typename... Args>
T (*Log( T (*FuncPtr)(Args...) ))(Args...)
{
    return FuncPtr;
}

int main()
{
    auto r = Log(Call<int(int), int>)([](int x){
        return x*10;
    }, 10);
    std::cerr << r << std::endl;
}

Ошибка:

> error: no matching function for call to 'Log'
>     auto r = Log(Call<int(int), int>)([](int x){
>              ^~~ test7.cpp:15:5: note: candidate template ignored: couldn't infer template argument 'T' T (*Log( T (*FuncPtr)(Args...)
> ))(Args...)
>     ^ 1 error generated.
4b9b3361

Ответ 1

Я считаю, что этот код неверен. Параметр функции Log не может использоваться для вывода аргумента шаблона в этом случае, потому что аргумент представляет собой невыводимый контекст.

Из [temp.deduct.type] в стандарте p5 перечисляет не выводимые контексты, а p5.5 говорит:

Параметр функции, для которого аргумент не может быть выполнен потому что связанный аргумент функции является функцией или набором перегруженные функции (13.4) и одно или несколько из следующих утверждений:

и p5.5.3 гласит:

набор функций, предоставляемых в качестве аргумента, содержит один или несколько функциональные шаблоны.

Моя интерпретация заключается в том, что у вас есть параметр функции, для которого аргумент функции является (указателем на) функцию, и эта функция является шаблоном функции.

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