Можно ли предположить, что идентичные лямбда-выражения имеют разные типы? - PullRequest
0 голосов
/ 18 мая 2018

Я экспериментирую с лямбдами и с тем, что разные лямбда-выражения имеют разные типы, даже если они одинаковы.Рассмотрим этот код

#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, то есть a и b, конечно, одного типа, а c другого типа.

Разрешено ли компилятору разрешать c того же типа, что и a?

Я имею в виду, что выражения идентичны, и это будет очевидной оптимизацией,

PS: Если захват предотвращает такую ​​оптимизацию, то как быть с лямбдами без захвата?

related: что такое сигнатура типа лямбда-функции c ++ 11 / 1y? и Можно ли выразить «тип» лямбда-выражения?

1 Ответ

0 голосов
/ 18 мая 2018

Разрешено ли компилятору разрешать c того же типа, что и a?

Нет.[&counter](){counter++;} является лямбда-выражением и для [expr.prim.lambda.closure] / 1 :

Тип лямбда-выражения (который также является типомобъект замыкания) - это уникальный, безымянный тип класса без объединения, называемый типом замыкания, свойства которого описаны ниже.

Таким образом, для каждого лямбда-выражения, даже если оно идентично предыдущемуодин, вы получите уникальный тип.

...