繁体   English   中英

复制std :: string时的MSVC 12 std :: initializer_list错误

[英]MSVC 12 std::initializer_list bug when copying std::string

我正在尝试使用MSVC 12(Visual Studio 2013,Update 4)创建一个C ++程序,该程序使用具有std::string成员的结构的std::initializer_list 我似乎遇到了MSVC中的错误。 这是一个显示问题的最小示例:

#include <cassert>
#include <initializer_list>
#include <string>

namespace
{
    struct TestStructure
    {
        std::string m_string;
        int m_integer;

        TestStructure(const std::string& string, int integer)
            : m_string(string), m_integer(integer)
        {
        }

        TestStructure(const TestStructure&) = default;
        ~TestStructure() = default;
        TestStructure& operator=(const TestStructure&) = default;
    };
}

int main(int, char **)
{
    TestStructure structure("foobar", 12345);
    std::initializer_list<TestStructure> structures({structure});

    assert(structure.m_integer == 12345);
    assert(structure.m_string == "foobar");
    assert(structures.size() == 1);
    assert(structures.begin()->m_integer == 12345);
    assert(structures.begin()->m_string == "foobar"); // abort()'s here.

    return EXIT_SUCCESS;
}

我希望该程序可以编译并执行而不会出现任何问题。 但是,当我运行它时,最后一个断言似乎失败了。 在Visual Studio调试器中查看,似乎structures.begin()->m_string == ""

我的程序是否格式不正确,或者实际上是MSVC中的错误? 是否有解决此问题的方法(除了不使用初始化列表以外)?

问题是您同时使用括号和花括号:

std::initializer_list<TestStructure> structures({structure});
                                               ^^         ^^

这将构造一个临时的std::initializer_list<TestStructure>并将其复制到structures 正常的生存期延长将不会执行,因此structures将指向已破坏的存储:

[dcl.init.list]

6-数组具有与任何其他临时对象(12.2)相同的生存期,只不过从数组initializer_list对象可以延长数组的生存期,就像将引用绑定到临时[...]

请注意,clang在这方面与MSVC一致; gcc在支持阵列上执行生命周期扩展,但是这样做是错误的(提起错误: https : //gcc.gnu.org/bugzilla/show_bug.cgi? id =66476 )。

如果要复制初始化(具有生存期扩展),请使用等号:

std::initializer_list<TestStructure> structures = {structure};

否则,请使用直接列表初始化(直接使用花括号):

std::initializer_list<TestStructure> structures{structure};

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM