C ++ Lambda как статический член в классе CRTP не компилируется в Visual Studio 15 - PullRequest
0 голосов
/ 18 декабря 2018

Я пытался создать набор классов политики, которые имеют различные операции, которые реализованы как лямбды-члены статические.Это сделано для того, чтобы я мог выбирать между различными версиями одной и той же операции в зависимости от заданной политики и передавать операцию какому-либо алгоритму, например std :: transform.

. Это привело меня к следующей схеме с использованием CRTP, гдебазовый класс реализует лямбду.Обратите внимание, что C ++ 17 позволяет определять лямбды constexpr.

namespace test
{
    template <class B>
    struct A
    {
        // The same thing happens if this is static const instead
        static constexpr auto t = [](const auto c) {};
    };

    struct C : A<C>
    {};
}

Когда я пытаюсь скомпилировать это, я получаю ошибки

error C2888: 'auto :: operator() (_ T1) const ': символ не может быть определен в пространстве имен' test '

ошибка C2888:' auto :: (_ T1) ': символ не может быть определен в пространстве имен' test '

ошибка C2888: ':: оператор unknown-type (__cdecl *) (_ T1) (__cdecl * (void) noexcept const) (_ T1)': символ не может быть определен в пространстве имен 'test'

...

с той же ошибкой для нескольких различных соглашений о вызовах.Однако следующий код без окружающего пространства имен компилируется просто отлично.

template <class B>
struct A
{
    static constexpr auto t = [](const auto c) {};
};

struct C : A<C>
{};

Я проверил , и первая версия компилируется как на gcc 8.2, так и на clang 7 с std = c ++17.Я что-то здесь упускаю или это ошибка?Я использую версию Visual Studio Community 15.9.4.

Заранее спасибо.

РЕДАКТИРОВАТЬ: кажется, что вы можете воспроизвести эту проблему, используя только простой класс со статической constexpr универсальная лямбдавнутри.Это не скомпилируется:

namespace test
{
    struct A
    {
        static constexpr auto t = [](auto c) {};
    };
}

Но это скомпилируется просто отлично.

struct A
{
    static constexpr auto t = [](auto c) {};
};

Наконец, первая версия работает, если лямбда не является универсальной.

namespace test
{
    struct A
    {
        static constexpr auto t = [](char c) {};
    };
}
...