尝试使用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&)'
这个答案将Boost适配器与C ++ 11 lambda一起使用建议将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这样可以防止您将其传递为纯类型,然后再调用它。Lambda也缺少构造函数。除非编译器注意到您的轻率手法,否则您可以构造无状态lambda(或对其的引用)然后调用它的hack方法,除非编译器注意到您的轻率手法,但这是未定义的行为。
这导致此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)
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句