I was trying to create a set of policy classes that have different operations which are implemented as static member lambdas. This is so that I could choose between different versions of the same operation based on the given policy and pass the operation to some algorithm such as std::transform.
This lead me to the following design using CRTP, where the base class implements the lambda. Note that C++17 allows one to define constexpr lambdas.
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>
{};
}
When I try to compile this, I get the errors
error C2888: 'auto ::operator ()(_T1) const': symbol cannot be defined within namespace 'test'
error C2888: 'auto ::(_T1)': symbol cannot be defined within namespace 'test'
error C2888: '::operator unknown-type (__cdecl *)(_T1)(__cdecl *(void) noexcept const)(_T1)': symbol cannot be defined within namespace 'test'
...
followed by the same error for a few different calling conventions. However, the following code without the surrounding namespace compiles just fine.
template <class B>
struct A
{
static constexpr auto t = [](const auto c) {};
};
struct C : A<C>
{};
I've checked and the first version compiles on both gcc 8.2 and clang 7 with std=c++17. Am I missing something here or is this a bug? I am using the Community edition of Visual Studio 15.9.4.
Thanks in advance.
EDIT: It seems that you can reproduce this issue using only a simple class with a static constexpr generic lambda inside. This fails to compile:
namespace test
{
struct A
{
static constexpr auto t = [](auto c) {};
};
}
But this compiles just fine.
struct A
{
static constexpr auto t = [](auto c) {};
};
Lastly, the first version works if the lambda is not generic.
namespace test
{
struct A
{
static constexpr auto t = [](char c) {};
};
}