30

This code works perfectly fine with gcc/g++ and msvc but not with clang. It keeps complaining that no matching function for Log was found, what is going on?

#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:

> 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.
qxz
3,8841 gold badge17 silver badges33 bronze badges
asked May 27, 2016 at 22:16
9
  • 3
    Even simpler: auto call = Call<int(int), int>; fails with error: variable 'call' with type 'auto' has incompatible initializer of type '<overloaded function type>'. The issue with Log is a red herring, the problem starts earlier - the compiler seems to have trouble figuring out what type Call<int(int), int> is. Commented May 27, 2016 at 22:30
  • 1
    Works if you replace result_ofdance with decltype(func(args...)) Commented May 27, 2016 at 22:34
  • Why is there an ampersand symbol std::result_of<Function &( ...)>? That looks out of place to me. Commented May 27, 2016 at 22:34
  • 9
    Even better, replace typename std::result_of<...>::type with std::result_of_t<...> and clang compiles it. That's... weird. Commented May 27, 2016 at 22:43
  • 1
    @ChrisBeck I threw out 27918, we'll see what smarter people say. Commented May 27, 2016 at 22:57

1 Answer 1

4

I believe that this code is incorrect. The function parameter to Log cannot be used for template argument deduction in this case because the argument is a non-deduced context.

From [temp.deduct.type] in the standard, p5 lists the non-deduced contexts, and p5.5 says:

A function parameter for which argument deduction cannot be done because the associated function argument is a function, or a set of overloaded functions (13.4), and one or more of the following apply:

and p5.5.3 says:

the set of functions supplied as an argument contains one or more function templates.

My interpretation is that you have a function parameter for which the function argument is a (pointer to) a function and that function is a function template.

Arguably, because this isn't an overload set, this might be something that could be allowed in the future, but I read the standard as not guaranteeing that this technique will work.

answered Aug 2, 2016 at 7:21
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.