2017-10-18 121 views

回答

1

在TI网站上没有太多有关此主题的内容,或者至少我不知道足够多的C++为您提供详细而准确的响应。

嵌入式ABI的实现在this document中描述,主要是衍生Itanium C++ ABI。它没有说明lambdas的实现,也没有说明关键字(或者我可能无法从文档中获取这些信息)。

因此,我决定直接测试在Energia。显然g++版本是4.6.3,因此它应该支持两者。

而且实际上(从一个编辑点,我没有我的MSP这里测试的代码),它可以编译这样的:

// In template.hpp 
#ifndef TEMPLATE_HPP_ 
#define TEMPLATE_HPP_ 

template<class T> 
T func(T a) { 
    auto c = [&](int n) { return n + a; }; 
    return c(0); 
} 

#endif /* TEMPLATE_HPP_ */ 

// in the sketch main 
#include "template.hpp" 

void setup() { int b = func<int>(0); } 
void loop() { }  

(模板工程只有在头,在主草图中产生错误)。为了编译这个草图,我不得不修改编辑器的一个内部文件。最大支持的标准似乎是-std=c++0x,并编译标志是这样的文件:

$ENERGIA_ROOT/hardware/energia/msp430/platform.txt 

在我安装的根就在/opt/energia。在该文件中,我修改了行32compiler.cpp.flags)并添加了该选项。请注意,-std=c++11不受支持(引发错误)。

compiler.cpp.flags=-std=c++0x -c -g -O2 {compiler.mlarge_flag} {compiler.warning_flags} -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -MMD 

不幸的是我有embedXcode :\

模仿std::function

std::function零经验不提供,因此你必须写某种类的模仿它。喜欢的东西:

// callback.hpp 
#ifndef CALLBACK_HPP_ 
#define CALLBACK_HPP_ 

template <class RET, class ARG> 
class Callback { 
    RET (*_f)(ARG); 

    public: 
    Callback() : _f(0) { }; 
    Callback(RET (*f)(ARG)) : _f(f) { }; 
    bool is_set() const { return (_f) ? true : false; } 
    RET operator()(ARG a) const { return is_set() ? _f(a) : 0; } 
}; 

#endif /* CALLBACK_HPP_ */ 

// sketch 
#include "callback.hpp"   
           // | !! empty capture! 
void setup() {    // V 
    auto clb = Callback<int, char>([](char c) { return (int)c; }); 
    if (clb.is_set()) 
    auto b = clb('a'); 
} 

void loop() {} 

可以做的工作,它使用一个简单的一招:

的λ-表达没有拉姆达捕获的闭合类型有公共非虚非-explicit const 转换函数指向功能指针具有与闭包类型的函数调用操作符相同的参数和返回类型。 [C++ 11标准5.1.2]

只要你离开捕获空,你放心有一个“转换”函数指针,因此,你可以将它存储没有问题。我写的代码:

  • 需要第一模板RET即返回类型
  • 需要第二个模板ARG是回调一个参数。在大多数情况下,您可能会考虑使用void*作为常见参数(在void指针中转换结构指针并将其用作参数,以在该函数中进行反转换操作,操作不需要任何费用)
  • 实现两个构造函数:空构造函数将函数指针初始化为NULL,而第二个直接分配回调。注意拷贝构造函数丢失,你需要实现它。
  • 实现了调用函数的方法(重载运算符())并检查回调是否实际存在。

还是那句话:这个东西有没有警告编译,但我不知道,如果它的MSP430,因为我无法测试它(它的工作原理常见的AMD64 Linux系统上)。

+0

哈我最终弄清楚了关于'-std = C++ 0x'的部分,但是没有机会在你之前发布一个答案。我实际上碰到了一种情况,我可以将lambda存储为类成员,从中受益匪浅。我怎么能没有std :: function(因为没有stl可用)? – Alexander

+0

也许模仿你自己的类的'std :: function'? (查看答案) –