C++ 在引入lambda之后,类内部函数是否有任何用例?

C++ 在引入lambda之后,类内部函数是否有任何用例?,c++,c++11,nested-class,lambda,C++,C++11,Nested Class,Lambda,来自关于Lambda函数和表达式的文章: 用户通常希望在位置附近定义谓词函数 他们在那里进行算法函数调用。这种语言只有一种 实现这一点的机制:在 功能。。。函数中定义的类不允许在模板中使用 这是否意味着在C++0x lambda就位后,在函数内部使用嵌套结构会被悄悄地弃用 另外,上段最后一行是什么意思?我知道嵌套类不能是模板;但这一行并不意味着这一点。在函数中定义结构从来都不是解决谓词缺乏问题的特别好的方法。如果你有一个虚拟的基地,它是有效的,但它仍然是一个相当丑陋的处理事情的方式。它可能看起来

来自关于Lambda函数和表达式的文章:

用户通常希望在位置附近定义谓词函数 他们在那里进行算法函数调用。这种语言只有一种 实现这一点的机制:在 功能。。。函数中定义的类不允许在模板中使用

这是否意味着在C++0x lambda就位后,在函数内部使用嵌套结构会被悄悄地弃用


另外,上段最后一行是什么意思?我知道嵌套类不能是
模板
;但这一行并不意味着这一点。

在函数中定义结构从来都不是解决谓词缺乏问题的特别好的方法。如果你有一个虚拟的基地,它是有效的,但它仍然是一个相当丑陋的处理事情的方式。它可能看起来有点像这样:

struct virtual_base {
  virtual void operator()() = 0;
};

void foo() {
  struct impl : public virtual_base {
    void operator()() { /* ... */ }
  };

  register_callback(new impl);
}
当然,如果您愿意,您仍然可以在函数中继续使用这些类——它们没有被弃用或损坏;他们只是从一开始就受到限制。例如,在C++之前,C++版本中的代码是非法的:

void foo() {
  struct x { /* ... */ };
  std::vector<x> y; // illegal; x is a class defined in a function
  boost::function<void()> z = x(); // illegal; x is used to instantiate a templated constructor of boost::function
}
void foo(){
结构x{/*…*/};
std::vector y;//非法;x是在函数中定义的类
boost::function z=x();//非法;x用于实例化boost::function的模板构造函数
}

这种用法实际上在C++0x中是合法的,因此,如果有什么不同的话,内部类的实用性实际上已经得到了扩展。不过,在大多数情况下,这仍然不是一种很好的做事方式。

我不确定我是否理解你的困惑,但我将陈述所有事实,让你解决。:)

在C++03中,这是合法的:

#include <iostream>

int main()
{
    struct func
    {
        void operator()(int x) const
        {
            std::cout << x << std::endl;
        }
    };

    func f; // okay
    f(-1); // okay

    for (std::size_t i = 0; i < 10; ++i)
        f(i) ; // okay
}
#包括
int main()
{
结构函数
{
void运算符()(int x)常量
{
标准::coutBoost.Variant

lambda不适用于变量,因为变量需要具有多个运算符()的对象(或具有模板化运算符()的对象)。C++0x现在允许在模板中使用本地类,因此
boost::apply_variant
可以接受它们

在引入lambda之后,类内部函数是否有任何用例

当然可以。在函数中包含一个类是关于:

  • 将其本地化为打算使用它的代码的私有实现细节
  • 防止其他代码使用和依赖它
  • 独立于外部名称空间的
显然,函数中有一个很大的类会损害可读性并混淆函数本身的流程,这是一个阈值——对于大多数开发人员和情况来说,这个阈值非常低。对于一个很大的类,即使只有一个函数打算使用它,将这两个类都放在单独的源文件中可能会更干净这都是根据口味调整的

你可以把它看作是类中的私有函数的倒数:在这种情况下,外部API是类的公共接口,函数保持私有。在这种情况下,函数使用一个类作为私有实现细节,后者也保持私有。C++是一种多范例语言,以及TLY在建模采办项目组织层次结构和API暴露方面提供了这种灵活性

示例:

  • 一个函数处理一些外部数据(比如文件、网络、共享内存等),并希望在I/O期间使用一个类来表示二进制数据布局;如果该类只有几个字段,并且对其他函数没有用处,它可能会决定将该类设为本地类
  • 函数希望对一些项进行分组并分配它们的数组,以支持它为导出其返回值而进行的内部计算;它可以创建一个简单的结构来封装它们
  • 给一个类一个讨厌的按位枚举,或者可能想重新解释
    浮点
    双精度
    以访问mantisa/指数/符号,并决定在内部使用
    struct
    和适当宽度的位字段对值建模以方便(注:实现定义的行为)
函数中定义的类不允许在模板中使用

我想你评论说其他人的回答解释了这一点,但无论如何

void f()
{
    struct X { };
    std::vector<X> xs;  // NOPE, X is local
}
void f()
{
结构X{};
std::vector xs;//不,X是本地的
}

正如Tony所提到的,函数中的类不仅与谓词有关。除了其他用例外,它还允许创建工厂函数,创建符合接口的对象,而无需公开实现类。请参见此示例:

#include <iostream>
/* I think i found this "trick" in [Alexandrescu, Modern C++ Design] */
class MyInterface {
    public:
        virtual void doSomethingUseful() = 0;
};

MyInterface* factory() {
    class HiddenImplementation : public MyInterface {
        void doSomethingUseful () {
            std::cout << "Hello, World!" << std::endl;
        }
    };

    return new HiddenImplementation();
}


int main () {
    auto someInstance = factory();

    someInstance->doSomethingUseful();
}
#包括
我想我在[亚历山大库,现代C++设计]中找到了这个“技巧”*
类MyInterface{
公众:
虚拟void dosomethingusseve()=0;
};
MyInterface*工厂(){
类HiddenImplementation:公共MyInterface{
void dosomethingusive(){

std::好吧,我正在为
template
partInteresting得到你的答案,你能再详细一点吗(一般来说,不只是为了boost)。这似乎是一个仍能保持内部结构活动的用例。我想你的意思是
apply\u visitor
。FWIW,我有一个
make\u visitor
工具,它接受不同的functor,并返回一个带有重载
操作符()
的functor,该操作符将委托给每个传递functor(如果存在任何歧义,则不会编译)这样我就可以将lambdas与
boost::variant
一起使用。我还发现我可以简单地传递一个例如Phoenix多态函子来适应它。因此,从我的角度来看,本地类并没有那么远,如果有的话。[如果有人对此感到好奇,我会定期聊天。]@吕克:这是个好主意,我之前想知道这样的实用程序是否实用。很高兴知道。嗨,埃夫努。很好的例子!+1来自我。干杯。
#include <iostream>

template <typename Func>
void exec(Func func)
{
    func(1337);
}

int main()
{
    struct func
    {
        // note: not possible in C++0x lambdas
        void operator()(const char* str) const
        {
            std::cout << str << std::endl;
        }

        void operator()(int val) const
        {
            std::cout << val << std::endl;
        }
    };

    func f; // okay
    f("a string, ints next"); // okay

    for (std::size_t i = 0; i < 10; ++i)
        f(i) ; // okay

    exec(f); // okay
}
void f()
{
    struct X { };
    std::vector<X> xs;  // NOPE, X is local
}
#include <iostream>
/* I think i found this "trick" in [Alexandrescu, Modern C++ Design] */
class MyInterface {
    public:
        virtual void doSomethingUseful() = 0;
};

MyInterface* factory() {
    class HiddenImplementation : public MyInterface {
        void doSomethingUseful () {
            std::cout << "Hello, World!" << std::endl;
        }
    };

    return new HiddenImplementation();
}


int main () {
    auto someInstance = factory();

    someInstance->doSomethingUseful();
}