Lambda作为模板参数

fja*_*sze 7 c++ lambda templates c++11

我发现那些类似的问题Lambda表达式作为类模板参数如何使用lambda表达式作为模板参数?,但即使有可用的答案我也不明白为什么以下代码不起作用(g ++ 4.8.2和g ++ - 4.9):

auto GoLess = [](int a,int b) -> bool
{
        return a < b;
};


template<typename Order>
struct foo
{
        int val;
        bool operator<(const foo& other)
        {
                return Order(val, other.val);
        }
};

typedef foo<decltype(GoLess)> foo_t;

int main()
{
        foo_t a,b;
        bool r = a < b;
}
Run Code Online (Sandbox Code Playgroud)

编译器输出是:

test.cpp: In instantiation of ‘bool foo<Order>::operator<(const foo<Order>&) [with Order = <lambda(int, int)>]’:
test.cpp:26:15:   required from here
test.cpp:17:30: error: no matching function for call to ‘<lambda(int, int)>::__lambda0(int&, const int&)’
   return Order(val, other.val);
                              ^
test.cpp:17:30: note: candidates are:
test.cpp:5:16: note: constexpr<lambda(int, int)>::<lambda>(const<lambda(int, int)>&)
 auto GoLess = [](int a,int b) -> bool
                ^
test.cpp:5:16: note:   candidate expects 1 argument, 2 provided
test.cpp:5:16: note: constexpr<lambda(int, int)>::<lambda>(<lambda(int, int)>&&)
test.cpp:5:16: note:   candidate expects 1 argument, 2 provided
Run Code Online (Sandbox Code Playgroud)

这段代码不应该有效吗?从我理解的其他线程中读取这些代码应该编译,但不是.

非常感谢

附录:

为了澄清一点,在上述问题中,KennyTM编写了以下代码:

auto comp = [](const A& lhs, const A& rhs) -> bool { return lhs.x < rhs.x; };
auto SetOfA = std::set <A, decltype(comp)> (comp);
Run Code Online (Sandbox Code Playgroud)

哪个应该工作,std :: set的第二个参数是'比较器',在这种情况下是一个lambda,在我的代码中我试图做同样的事情或者至少我认为我在做同样的事情,但是我的代码无效.我的代码中缺少的东西?

还请注意来自Lambo 表达式中的 Xeo 作为类模板参数

auto my_comp = [](const std::string& left, const std::string& right) -> bool {
  // whatever
}

typedef std::unordered_map<
  std::string,
  std::string,
  std::hash<std::string>,
  decltype(my_comp)
  > map_type;
Run Code Online (Sandbox Code Playgroud)

这应该是有效的.哪里是我的错?

谢谢

ric*_*ici 9

正如编译器有用地告诉你的那样,问题在于这一行:

return Order(val, other.val);
Run Code Online (Sandbox Code Playgroud)

既然Order是一个类型(而不是函数),那就是调用Order的双参数构造函数.但它没有一个.

调用功能类的正确语法是:

return Order()(val, other.val);
Run Code Online (Sandbox Code Playgroud)

但是,这不起作用,因为为lambda生成的类具有已删除的默认构造函数.

简而言之,您需要使用(唯一的)lambda实例来实例化您的类.

这是一种可行的方法:

template<typename Order>
struct foo {
    foo(Order compare) : compare_(compare) {}
    bool operator<(const foo& other) {
        return compare_(val, other.val);
    }
    int val;
    Order compare_;
};

/* In practice, you'll want to template a parameter pack
 * for the other arguments to the constructor, since those are likely.
 * Also, you might want to use std::forward.
 */
template<typename Order>
foo<Order> foomaker(Order order) {
    return foo<Order>(order);
}

int main() {
    auto GoLess = [](int a,int b) -> bool
        {
             return a < b;
        };

    auto a = foomaker(GoLess);
    auto b = foomaker(GoLess);
    bool r = a < b;
    return r;
}
Run Code Online (Sandbox Code Playgroud)