我试图创建一组具有不同操作的策略类,这些策略类被实现为静态成员lambda。这样一来,我就可以根据给定的策略在同一操作的不同版本之间进行选择,并将该操作传递给诸如std :: transform之类的算法。
这使我进入使用CRTP的以下设计,其中基类实现lambda。请注意,C ++ 17允许定义constexpr lambda。
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>
{};
}
当我尝试编译它时,我得到了错误
错误C2888:'auto :: operator()(_ T1)const':无法在名称空间'test'中定义符号
错误C2888:'auto ::(_ T1)':无法在名称空间'test'中定义符号
错误C2888:':: operator 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>
{};
我已经checked,第一个版本在gcc 8.2和clang 7上都使用std = c ++ 17进行编译。我在这里缺少什么还是这是一个错误?我正在使用Visual Studio 15.9.4的社区版。
谢谢。
编辑: 似乎您可以仅使用内部带有静态constexpr通用lambda的简单类来重现此问题。 无法编译:
namespace test
{
struct A
{
static constexpr auto t = [](auto c) {};
};
}
但这可以编译。
struct A
{
static constexpr auto t = [](auto c) {};
};
最后,如果lambda不是通用的,则第一个版本适用。
namespace test
{
struct A
{
static constexpr auto t = [](char c) {};
};
}