Общая лямбда не может быть использована в пространстве имен?

Рассмотрим следующий фрагмент кода

#include <iostream>
#include <functional>

namespace A {
    template<typename T>
    struct X {
        using Function = std::function<int(T)>;
        static Function f;
    };

    template<typename T>
    typename X<T>::Function X<T>::f = [](auto) { return 42; };

}

int main() {
    std::cout << A::X<int>::f(0);
}

И GCC, и Clang принимают этот код, но MSVC (протестированная версия 19.00.23506) дает:

error C2888: 'auto <lambda_ce48e25aa4b9e3d225584044e4eae9e2>::operator ()(_T1) const': symbol cannot be defined within namespace 'A'

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

Может кто-нибудь объяснить, в чем проблема MSVC видит в этом коде? Ограничивает ли C++ Standard использование общих лямбд в контекстах, подобных описанным выше?

1 ответ

Решение

Да, это ошибка MSVC, но она была исправлена ​​в VS2017 15.6 preview 2.0

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

POC этой проблемы можно найти здесь: https://godbolt.org/g/BESMK4

MSVC не может сделать вывод, что auto это точно T в любом случае и не получается.

Если вам нужно, чтобы он работал с MSVC, замените auto с явным T:

template<typename T>
typename X<T>::Function X<T>::f = [](T) { return 42; };

https://godbolt.org/g/cYG9GC

Другие вопросы по тегам