带()的C++ lambda和不带()的lambda有什么区别?

5
这两个代码块有什么区别?
struct HighResClock
{
    typedef long long                               rep;
    typedef std::nano                               period;
    typedef std::chrono::duration<rep, period>      duration;
    typedef std::chrono::time_point<HighResClock>   time_point;
    static const bool is_steady = true;

    static time_point now();
};


namespace
{
    auto g_Frequency = []() -> long long
    {
        std::cout<<"HERE";
        LARGE_INTEGER frequency;
        QueryPerformanceFrequency(&frequency);
        return frequency.QuadPart;
    }();
}

HighResClock::time_point HighResClock::now()
{
    LARGE_INTEGER count;
    QueryPerformanceCounter(&count);
    return time_point(duration(count.QuadPart * static_cast<rep>(period::den) / g_Frequency));
}

int main()
{
    HighResClock c;
    c.now();
    c.now();
    c.now();
}

并且

struct HighResClock
{
    typedef long long                               rep;
    typedef std::nano                               period;
    typedef std::chrono::duration<rep, period>      duration;
    typedef std::chrono::time_point<HighResClock>   time_point;
    static const bool is_steady = true;

    static time_point now();
};


namespace
{
    auto g_Frequency = []() -> long long
    {
        std::cout<<"HERE";
        LARGE_INTEGER frequency;
        QueryPerformanceFrequency(&frequency);
        return frequency.QuadPart;
    };
}

HighResClock::time_point HighResClock::now()
{
    LARGE_INTEGER count;
    QueryPerformanceCounter(&count);
    return time_point(duration(count.QuadPart * static_cast<rep>(period::den) / g_Frequency()));
}

int main()
{
    HighResClock c;
    c.now();
    c.now();
    c.now();
}

如果您没有注意到,区别在于下面的括号:

auto g_Frequency = []() -> long long
{
    LARGE_INTEGER frequency;
    QueryPerformanceFrequency(&frequency);
    return frequency.QuadPart;
}(); //this bracket here appears in one and not the other..

我问这个问题是因为只有带括号的那个代码会打印一次"Here",而不带括号的代码会打印三次。括号的意思和作用是什么?这种使用括号的语法有一个名称吗?

1
这里有一个是HERE,另一个是Here :) - Noam Rathaus
哈哈哈哈..幽默加一分。我是指括号。这是我第一次在lambda后面看到括号,我在网上找不到其他的例子。 - Brandon
我希望我知道它们之间的区别,我从未见过“auto”,所以我不确定它的作用,也不知道= []()是什么..抱歉,通常在结尾处使用()表示执行而不是分配值。 - Noam Rathaus
2个回答

8

在lambda定义[]{}();后立即编写(),将调用lambda,因此结果的类型是lambda返回类型。

如果省略()后缀,则返回一个未指定的lambda类型,它基本上是一个可调用的函数对象。

auto result = []{ return 42; }(); // auto is integer, result has 42 in it  
auto result1 = []{ return 42; }; // auto is some unspecified lambda type  
auto result2 = result1(); // auto is integer, result2 is storing 42` 
......................^^ - this is the bracket you can also put directly after the definition of the lambda

谢谢!我真的看不出来。所以,带有括号的g_Frequency是一个返回类型的变量,而没有括号的g_Frequency是一个lambda表达式?编辑:一旦它让我接受,我就会接受它。 - Brandon
1
@CantChooseUsernames 是的,我包含了一个例子。 - ScarletAmaranth

1
实际上,这两个代码段之间有两个不同之处:
  1. 一个代码段在lambda后立即执行括号,并产生一个long,而在使用g_Frequency时没有括号,仅读取其值。
  2. 另一个代码段在lambda后没有括号,即g_Frequency成为函数对象,在使用g_frequency时有括号,使其成为对函数的调用。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接