Lamba 依赖模板依赖值作为该模板构造函数的默认值在 MSVC 上失败

Lamba depending on template depending value as default value of constructor of that template fails on MSVC

我刚刚升级了我的 msvc,遇到了麻烦。

这是在我的旧代码中重现问题的最小完整可验证示例:

#include <functional>

#define VERSION 1

template<typename T>
class Foo
{
public:
    static constexpr int bar = 512;

#if VERSION == 1
    Foo(std::function<int()> f = []() { return Foo<T>::bar;})
#elif VERSION == 2
    Foo(std::function<int()> f = []() { return Foo::bar;})
#elif VERSION == 3
    Foo(std::function<int()> f = []() { return bar;})
#elif VERSION == 4
    Foo(std::function<int()> f = [bar = Foo<T>::bar]() { return bar;})
#endif
        : m_f{std::move(f)}
    {}

public:
    std::function<int()> m_f;
};


void use()
{
    Foo<int> foo;
}

Live demo

VERSION 定义为 1 时,这与我的原始代码类似。 我还必须支持 clang 和 gcc。 Curretly 我的项目正在使用 C++17 标准(我的项目可能在明年或两年内使用 C++20)。

我正在寻找一些不错的解决方法,它不需要讨厌的 #if 并涵盖所有编译器(旧新 msvc gcc clang)。

VERSION 的其他值展示了我到目前为止所做的尝试(总是有些编译器失败)。

VERSION which compilers fails
1 msvc 19.28
2 msvc 19.28, msvc 19.27, msvc 19.25
3 msvc all versions
4 clang 11.0

如果有人知道 MSVC 的相应错误报告 link 也很好。

最简单的解决方法是将常量移动到全局范围,但我更愿意避免这种情况。

静态函数完成工作:

static std::function<int()> defaultF() {return []() { return bar;};}

Foo(std::function<int()> f = defaultF())
    : m_f{std::move(f)}
{}

Demo