C++:在另一个函数中声明一个函数有什么用?
C++: what's the usage of declaring a function inside another function?
Stanley Lippman的"C++入门"在第234页提到
通常,在本地声明函数是一个坏主意。然而 为了解释作用域如何与重载交互,我们将违反这一点 练习和使用本地函数声明。
...
void print(const string &);
void print(double); // overloads the print function
void fooBar(int ival)
{ ...
// bad practice: usually it's a bad idea to declare functions at local scope
void print(int); // new scope: hides previous instances of print
print(ival); // ok: print(int) is visible
print(3.14); // ok: calls print(int); print(double) is hidden
}
然而,在函数主体内声明一个函数,在哪种情况下这样做是有意义的?
我记得 Scheme 中的类似代码:
(define (PowerSet set)
(if (null? set) '(())
(let ((PowerSetAfterHead (PowerSet (cdr set) ) ))
(append PowerSetAfterHead
(PowerSet (cdr set) )
(map
(lambda (subset)
(cons (car set) subset
)
)
(PowerSet (cdr set) )
)
)
)
)
)
它是否通常用于隐藏仅供外部函数使用的"本地函数"的滥用? 类似于内部类的东西?或者它在某些设计模式中有用吗?
当调用函数时存在歧义时,就会出现问题。因此,为了避免某些作用域中的歧义,您可以重新声明所需的函数,该函数隐藏了与外部作用域同名的所有其他函数。
请考虑以下简单示例。如果运行以下程序
#include <iostream>
void f( int ) { std::cout << "f( int )" << std::endl; }
void f( double ) { std::cout << "f( double )" << std::endl; }
int main()
{
f( 10l );
return 0;
}
你会得到一个错误,比如
prog.cpp:10:9:错误:重载的"f(long int)"调用不明确 f( 10l );
但是如果你像这样在main中添加函数f的声明
#include <iostream>
void f( int ) { std::cout << "f( int )" << std::endl; }
void f( double ) { std::cout << "f( double )" << std::endl; }
int main()
{
void f( double );
f( 10l );
return 0;
}
代码将被编译,输出将如下所示
f( double )
您的方案示例既声明又定义局部函数。
C++示例只是在本地声明一个函数。
这些是不同的东西。
您可以在 C++11 中使用 lambda 创建方案局部函数的粗略等效项。
在本地声明一个函数只是说"存在一个具有这个名称和签名的函数"。 更重要的是,它在比函数外部的函数更窄的范围内这样做,并且由于只有所述较窄范围内的函数才考虑重载(而不是更广泛范围内的函数)。
不会创建新函数 - 必须在其他地方定义它。 (你不能在C++中定义本地函数,除非像本地类方法和lambdas这样的东西)
您可以使用它来更改重载分辨率的工作方式,但这很少是一个好主意。 如果存在重载歧义,最好手动转换类型,然后调用重载集,并使其正常解决。
另一种方法是仅声明要调用的重载,然后调用它。 这可能会导致令人惊讶的行为,因此如果可以的话,只在非常狭窄的范围内这样做,并记录您为什么要这样做以及可能发生的问题(因为很少有程序员会在没有至少一点提示的情况下阅读代码时在大脑的前部设置范围隐藏重载规则)。
我认为我从来没有遇到过必须在本地声明函数的情况。
我这样做的几次是因为我正在入侵一些严重的泥浆代码,并希望出于原型/调试目的进行极其本地化的更改。 我只是声明了一个函数签名并在某处调用它。 该函数是其他地方同一库中另一个.cpp文件中的静态本地函数,我删除了那里的静态并测试了调用它的结果。
这节省了创建一个头文件(或修改一个),正式公开它,包括我们使用它的所述头。 在投入生产之前,我会完成这样的步骤(并且可能会在我使用它时清理该静态本地函数的接口)。
因此,我将其用于快速而肮脏的原型黑客。 上次我这样做时,我最终在进行原型黑客攻击后将其还原,这更容易,因为我在 2 个位置只接触了 1 个文件。
- 函数向量_指针有不同的原型,我可以构建一个吗
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 创建一个函数以在输入为负数或零时输出字符串.第一次执行用户定义的函数
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- 如何仅为一个函数添加延迟
- 构造函数正在调用一个使用当前类类型的函数
- C++-试图将函数指针推回到另一个CPP文件中的矢量时出错
- 有一个打印语句的函数是一种糟糕的编程实践吗
- 有没有什么方法可以使用一个函数中定义的常量变量,也可以由c++中同一程序中的其他函数使用
- 输入到文件并输出到另一个文件,并将流文件传递给函数
- 我不明白为什么我声明一个空的内部结构并将其传递给构造函数
- 如何创建函数管道,以便函数一个接一个地运行?
- 如何巧妙地编写两个函数——一个用于检查是否存在解决方案,另一个用于获取所有解决方案
- 在c++中的复制构造函数/一个声明语句中的初始化的延续中使用chain方法
- C :基类调用自己的虚拟函数 - 一个反图案
- 如何在这个交换函数(一个单独的链表)中找到错误
- 两个相同的函数(一个使用模板模式,另一个不使用)
- 你怎么能一次给一个函数一个参数呢
- 为什么要做两个函数?(一个是非const,另一个是const)
- 当代码在其他地方使用时,如何保证函数一个接一个地被调用