首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么我不能在另一个函数中定义一个函数?

为什么我不能在另一个函数中定义一个函数?
EN

Stack Overflow用户
提问于 2015-04-30 19:58:52
回答 11查看 30.4K关注 0票数 82

这不是lambda函数的问题,我知道我可以将lambda赋值给一个变量。

允许我们声明而不是在代码中定义函数的意义是什么?

例如:

代码语言:javascript
复制
#include <iostream>

int main()
{
    // This is illegal
    // int one(int bar) { return 13 + bar; }

    // This is legal, but why would I want this?
    int two(int bar);

    // This gets the job done but man it's complicated
    class three{
        int m_iBar;
    public:
        three(int bar):m_iBar(13 + bar){}
        operator int(){return m_iBar;}
    }; 

    std::cout << three(42) << '\n';
    return 0;
}

所以我想知道的是,为什么C++会允许看起来无用的two,和看起来复杂得多的three,但不允许one

编辑:

从答案上看,代码中的声明似乎能够防止名称空间污染,但我希望听到的是,为什么允许声明函数的能力,而不允许定义函数的能力。

EN

回答 11

Stack Overflow用户

回答已采纳

发布于 2015-04-30 22:30:11

不允许使用one的原因并不明显;嵌套函数是很久以前在N0295中提出的,它说:

我们讨论了在C++中引入嵌套函数。嵌套函数很容易理解,它们的引入几乎不需要编译器供应商、程序员或委员会的努力。嵌套函数提供了显著的优势,...

显然,这个提议被拒绝了,但由于我们没有1993的在线会议记录,我们没有这个拒绝的理由的可能来源。

事实上,这个提议在中被认为是一种可能的替代方案:

其中一篇文章Bre88和proposal N0295 to

C ++ SH93建议向C ++添加嵌套函数。嵌套函数类似于lambda表达式,但定义为函数体中的语句,除非该函数处于活动状态,否则不能使用结果闭包。这些建议也不包括为每个lambda表达式添加新类型,而是更像普通函数一样实现它们,包括允许特殊类型的函数指针引用它们。这两个提案都早于向C ++添加模板之前,因此没有提到将嵌套函数与通用算法结合使用。此外,这些提议无法将局部变量复制到闭包中,因此它们生成的嵌套函数在其封闭函数之外完全不可用

考虑到我们现在已经有了lambdas,我们不太可能看到嵌套函数,因为正如论文概述的那样,它们是解决相同问题的替代方案,并且嵌套函数相对于lambdas有几个限制。

至于你问题的这一部分:

//这是合法的,但我为什么要这样做?int two(int bar);

在某些情况下,这将是一种调用所需函数的有用方法。3.4.1 basic.lookup.unqual的C++标准草案部分给了我们一个有趣的例子:

代码语言:javascript
复制
namespace NS {
    class T { };
    void f(T);
    void g(T, int);
}

NS::T parm;
void g(NS::T, float);

int main() {
    f(parm); // OK: calls NS::f
    extern void g(NS::T, float);
    g(parm, 1); // OK: calls g(NS::T, float)
}
票数 41
EN

Stack Overflow用户

发布于 2015-04-30 20:13:18

好吧,答案是“历史原因”。在C中,您可以在块范围内使用函数声明,而C++设计者看不到删除该选项的好处。

示例用法如下:

代码语言:javascript
复制
#include <iostream>

int main()
{
    int func();
    func();
}

int func()
{
    std::cout << "Hello\n";
}
票数 31
EN

Stack Overflow用户

发布于 2015-04-30 20:18:35

在您给出的示例中,void two(int)被声明为外部函数,该声明仅在main函数的作用域内有效。

如果您只想让名称twomain()中可用,以避免污染当前编译单元中的全局名称空间,那么这是合理的。

回复评论的示例:

main.cpp:

代码语言:javascript
复制
int main() {
  int foo();
  return foo();
}

foo.cpp:

代码语言:javascript
复制
int foo() {
  return 0;
}

不需要头文件。编译和链接

代码语言:javascript
复制
c++ main.cpp foo.cpp 

它将编译并运行,程序将如预期的那样返回0。

票数 23
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29967202

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档