Q:

What's wrong with this (simple) lambda function? 

There's something wrong with the captured variable, but I can't figure out what.  The error I'm getting is 
error: no matching function for call to ‘applyFunc(int, main()::<lambda(int)>)’
  applyFunc<int,int>(0,[=](int z) -> int{return z + xx;}); //error! 

Any insight on what's wrong? 
//given input x and function func, return func(x)
template <typename T, typename U>
U applyFunc( T x, U func(T) )
{
    return func(x);
}

int main()
{
    int xx = 2;
    applyFunc<int,int>(0,[](int x) -> int {return x + 1;}); //no error
    applyFunc<int,int>(0,[=](int z) -> int{return z + xx;}); //error! 

    return 0;
}

EDIT: Fix with function object from < functional >. 
#include <functional>

template <typename RET, typename INPUT>
RET applyFunc( INPUT x, std::function<RET(INPUT)> func )
{
    return func(x);
}

int aFunc(int x)
{
    return x;
}

int main()
{
    int xx = 4;
    applyFunc<int,int>(0,[](int x) -> int {return x + 1;});
    applyFunc<int,int>(0,[=](int z) -> int{return z + xx;});

    return 0;
}

A:

Your parameter func is declared as a regular function pointer.  Lambdas are not regular functions.  Yet lambdas are convertible to regular function pointers, but only if they have empty capture clause. 
Lambda 
[](int x) -> int {return x + 1;}

has empty capture clause, which makes it convertible to function pointer type int (*)(int).  
Lambda 
[=](int z) -> int{return z + xx;}

has non-empty capture clause, which means that it is not convertible to a regular function pointer. 

Your idea to use std::function will make your code compile and work.  However, there is an inherent inefficiency in this approach.  std::function is an implementation of type erasure technique based on run-time polymorphism.  One of its main purposes is to facilitate switch from compile-time polymorphism to run-time polymorphism, thus reducing "templatization" of the code.  Basically, by using std::function you agree to the run-time overhead hidden in std::function implementation in order to reduce the template-induced code bloat. 
This issue does not apply to your specific code.  Your template function is small and dependent on compile-time arguments in every aspect.  Your function is purely conceptual and should dissolve (disappear) entirely in the resultant code.  In such cases you want it to work through compile-time polymorphism.  Bringing in std::function just to make it compile does not look like the right idea.  This is shooting sparrows with a cannon and paying for the overhead. 
What you could do instead (as the first step) is just add another template parameter for functor type
template <typename T, typename U, typename F>
U applyFunc( T x, F func )
{
    return func(x);
}

As the second step, you'd immediately notice that template parameter U is now excessive: it is implicitly brought in by the combination of T and F. By extracting this type from F you can rewrite your template as
template <typename T, typename F>
std::result_of_t<F(T)> applyFunc( T x, F func )
{
    return func(x);
}

(This can be further improved by using "perfect forwarding" features of the language.) 
Note that this also enables full deduction of function template arguments by the compiler, so you will no longer have to specify them explicitly
int xx = 2;
applyFunc(0,[](int x) { return x + 1; });
applyFunc(0,[=](int z) { return z + xx; });

One can also note that we can even try to get rid of T as template parameter (extracting it from F), but I wouldn't do that.  Keeping T flexible makes the template to support natural concept of function overloading. 

A:

I cannot make comment to markyxl answer, so I will provide another one.  Instead of specifying return type, you can use auto and decltype:
#include <iostream>
using namespace std;

template <typename T, typename U>
auto applyFunc(T x, U func) -> decltype(func(x))
{
  return func(x);
}

int main()
{
  int xx = 2;
  bool a = applyFunc<bool>(0,[](int x) -> bool {return x > 0;});
  bool b = applyFunc<bool>(0,[=](int z) -> bool {return z + xx > 0;});

  cout << "a = " << a << " b = " << b << endl;
}

