首页 > 解决方案 > EBO、多重继承和 MVSC++

问题描述

我在运行基于 MVS2019 构建的代码时遇到了问题。问题是“运行时检查失败 #2 - 变量‘函数’周围的堆栈已损坏。”。我在网上搜索了答案,发现原因是 EBO 在 MVS 上的多重继承中存在一些好奇心:https ://developercommunity.visualstudio.com/content/problem/344224/class-derive-from-lambda-corrupt-stack .html

这是代码:

template <typename... Callables>
struct overload : public Callables...
{
    using Callables::operator()...;
};

template <typename... Callables>
overload(Callables...)->overload<Callables...>;

enum class Type
{
    Double,
    Int,
};

TEST(overload_test, test)
{
    int i = 0;

    const overload function
    {
        [](int) { return Type::Int; },
        [i](double) { auto a = i; return Type::Double; },
    };

    //const overload function // in this case I get the error
    //{
    //  [i](double) { auto a = i; return Type::Double; },
    //  [](int) { return Type::Int; },
    //};

    EXPECT_EQ(function(0.0), Type::Double);
    EXPECT_EQ(function(0), Type::Int);
}

我发现了如何解决这个问题 - 使用这样的宏:

#if defined(_MSC_VER)
#   define EMPTY_BASES __declspec(empty_bases)
#else
#   define EMPTY_BASES
#endif

template <typename... Callables>
struct EMPTY_BASES overload : public Callables...
...

它适用于我的混凝土案例!但我继续使用不同的有状态和无状态 lambda 以及 std::functions 对其进行测试,并意识到在某些情况下,我仍然会得到错误,而不取决于使用/不使用宏(请参阅上面代码中的注释。

现在我有时会出现“运行时检查失败 #2 - 变量‘函数’周围的堆栈已损坏。” 使用宏和不使用宏时出错!这取决于函子的顺序和它们的状态。我想知道是否有可能在 Visual Studio 上完成这种漂亮的重载工作。

标签: c++visual-studioc++17

解决方案


推荐阅读