尝试使用 C++11 lambda 作为 boost::multi_index
的关键访问器:
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/global_fun.hpp>
struct Foobar {
int key;
};
void func()
{
namespace mii = boost::multi_index;
typedef boost::multi_index_container< Foobar,
mii::hashed_unique< mii::global_fun< const Foobar &, int,
[]( const Foobar &f ) { return f.key; } > > > Container;
}
但是从 g++ 4.8.2 和 boost 1.53 得到编译错误:
error: could not convert template argument '<lambda closure object>func()::__lambda0{}' to 'int (*)(const Foobar&)'
这个答案Using Boost adaptors with C++11 lambdas建议转换为 std::function
,这在这种情况下不起作用。有解决此问题的简单方法吗?
最佳答案
Lambda 不能用于未计算的上下文1。我不确定这是否符合未评估上下文的条件,但涉及 decltype( [](int){} )
的方法将2。
无状态 Lambda 似乎没有 constexpr
转换为函数指针(这可能是一个疏忽),否则这会起作用:
template<class T>using type=T;
template< void(*)(int) > struct test {};
constexpr type<void(int)>* f = [](int){};
int main() {
test<f> x;
}
如果您将 lambda 直接传递给 void(*)(int)
函数指针参数,它甚至可能会起作用。
这让您只能将 lambda 编写为老式函数。
1 这可能是为了让编译器的工作更轻松(据我所知,在当前标准下,头文件中的 lambda 类型不需要在编译单元之间保持一致?但是我我不确定。)
2 这可以防止您将其作为纯类型传递然后调用它。 Lambdas 也缺少构造函数。您构造无状态 lambda(或对其的引用)然后调用它的 hack 将在每个实现中都有效,除非编译器注意到您的轻微手,但这是未定义的行为。
这导致了这个黑客攻击:
#include <iostream>
auto f() { return [](){std::cout <<"hello world.\n";}; }
template<class Lambda>
struct test {
void operator()() const {
(*(Lambda*)nullptr)();
}
};
int main() {
test<decltype(f())> foo;
foo();
}
这是无用且未定义的行为,但确实调用了我们作为模板参数传递给 test
技术上的 lambda。 (C++14)
关于c++ - 将 C++11 lambda 与 boost::multi_index 结合使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25790359/