假设相同的 lambda 表达式具有不同的类型是否安全?

2024-02-07

我正在试验 lambda,事实上不同的 lambda 表达式具有不同的类型,即使它们是相同的。考虑这段代码

#include <iostream>

template <typename T> void once(T t){
    static bool first_call = true;
    if (first_call) t();
    first_call = false;
}

int main() {    
    int counter = 0;
    auto a = [&counter](){counter++;};
    once(a);
    once(a);
    std::cout << counter;              // 1

    auto b = a;                        // same type
    once(b);
    std::cout << counter;              // 1

    auto c = [&counter](){counter++;}; // different type
    once(c);
    once(c);               
    std::cout << counter;              // 2
}

这打印112, ie a and b当然是同一类型并且c有不同的类型。

编译器是否允许让c属于同一类型a?

我的意思是表达式是相同的,这将是一个明显的优化。

PS:如果捕获阻止了这种优化,那么没有捕获的 lambda 又如何呢?

有关的:c++11/1y lambda 函数的类型签名是什么? https://stackoverflow.com/questions/21657627/what-is-the-type-signature-of-a-c11-1y-lambda-function and lambda 表达式的“类型”可以表达吗? https://stackoverflow.com/questions/3867276/can-the-type-of-a-lambda-expression-be-expressed?rq=1


编译器是否允许让c属于同一类型a?

No. [&counter](){counter++;}是一个 lambda 表达式并且 per[expr.prim.lambda.closure]/1 http://eel.is/c++draft/expr.prim.lambda#closure-1.sentence-1:

lambda 表达式的类型(也是闭包对象的类型)是唯一的、未命名的非联合类类型,称为闭包类型,其属性如下所述。

因此,对于每个 lambda 表达式,即使它与前一个表达式相同,您也会得到一个唯一的类型。

您可以使用typeid检查情况是否如此:

#include <iostream>
#include <typeinfo>

template <typename T> void once(T t){
    static bool first_call = true;
    std::cout << typeid(t).name() << std::endl;
    if (first_call) {
        t();
    }
    first_call = false;
}

int main() {    
    int counter = 0;
    auto a = [&counter](){counter++;};
    once(a);
    once(a);
    std::cout << counter << std::endl; // 1

    auto b = a;                        // same type
    once(b);
    std::cout << counter << std::endl; // 1

    auto c = [&counter](){counter++;}; // different type
    once(c);
    once(c);               
    std::cout << counter << std::endl; // 2
}

result:

Z4mainEUlvE_                                                                                                          
Z4mainEUlvE_                                                                                                          
1                                                                                                                     
Z4mainEUlvE_                                                                                                          
1                                                                                                                     
Z4mainEUlvE0_                                                                                                         
Z4mainEUlvE0_                                                                                                         
2

你可以看到有两个函数模板实例化。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

假设相同的 lambda 表达式具有不同的类型是否安全? 的相关文章

随机推荐