Я пытался создать набор классов политики, которые имеют различные операции, которые реализованы как лямбды-члены статические.Это сделано для того, чтобы я мог выбирать между различными версиями одной и той же операции в зависимости от заданной политики и передавать операцию какому-либо алгоритму, например 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) {};
};
}