处理范围变量的内部函数

时间:2012-01-02 08:06:13

标签: c++ lambda

我有一段这样的代码:

std::list<boost::shared_ptr<Point> > left, right;
// ... fill lists ...

// now, calculate the angle between (right[0], right[1]) and (right[0], left[0])
double alpha = angle(*(right.begin()->get()), *(((++right.begin()))->get()), *(left.begin()->get()) );

std::cout << alpha * 180 / M_PI << std::endl;

if(alpha < 0){
    // do something with the lists, like reversing them. Especially the beginning and end of the lists may change in some way, but "left" and "right" are not reassigned.
}

// calculate the new alpha
alpha = angle(*(right.begin()->get()), *(((++right.begin()))->get()), *(left.begin()->get()) );

除了迭代器增量魔法,在没有注释的情况下可能不会太过于obvoius,我想定义一个函数double alpha()来减少重复。但是因为这个功能的使用非常具体,所以我想把它变成一个本地功能。理想情况是这样的:

int a, b;
int sum(){ return a + b; }
a = 5; b = 6;
int s = sum(); // s = 11
a = 3;
s = sum(); // s = 9 now

在像Python这样的语言中,这是完全可以的,但是如何在C ++中完成这个?

编辑:

这就是我最终的结果,特别感谢@wilx和-std=c++0x编译器标志:

auto alpha = [&right, &left]() {

    // not 100% correct due to my usage of boost::shared_ptr, but to get the idea

    Point r_first = *(right.begin()); 
    Point l_first = *(left.begin());
    Point r_second = *(++right.begin());

    return angle(r_first, r_second, l_first);
};


if(alpha() < 0) // fix it

double new_alpha = alpha();

3 个答案:

答案 0 :(得分:2)

C ++不支持嵌套函数,但可以使用函数作用域进行解决方法:

void scopeFnc()
{
  struct Inner
  {
     static int nestedFnc() { return 5; }
  };

  int a = Inner::nestedFnc();
}

答案 1 :(得分:1)

在这种情况下,我建议使用像angle2(std::list<Point> const &, etc.)这样的重载。两个简单的论点比现在的好。

使用C ++ 11,你可以使用lambda来通过引用来捕获它们的参数。

如果您不能使用C ++ 11而且您确实喜欢冒险,请尝试使用Boost.Phoenix(Boost.Spirit的一部分)。

答案 2 :(得分:0)

据我所知,C ++不允许这样做。您可以通过将静态限定符附加到alpha的函数签名的开头来限制创建的名称空间污染,但您仍然必须单独定义它。

这将使名称仅在该源文件中使用。您还可以在函数中定义一个宏,如果您以后不想要预处理器的怪异,请小心取消它。

int a, b;
#define SUM() (a+b)
int s=sum()
#undef SUM