【问题标题】:std::for_each seems to be cleaning std::stringstd::for_each 似乎正在清理 std::string
【发布时间】:2020-09-08 02:41:38
【问题描述】:

我正在使用 STL 在 c++17 中制作一个简单的蛇游戏,但在将板 (std::vector) 解析为 std::string 时遇到问题。我将 std::for_each 与我的自定义函子一起使用。下面是解析方法:

std::string Board::parseBoardToString()
{
    boardToString.resetStringBoard();
    std::for_each(v_board.begin(), v_board.end(), boardToString);
    return boardToString.getStringBoard();
}

Functor 原型(有些方法是测试用的,没关系):

class BoardToString
{
    public:
        BoardToString(unsigned _width);
        void operator()(char _cell);
        void resetStringBoard();
        std::string getStringBoard();
        void printStringBoard();
    private:
        bool isItLastLine();
        void resetCharsToNewLine();
        std::string stringBoard;
        const unsigned U_WIDTH;
        unsigned charsToNewLine;
};

还有 operator() 的实现:

void BoardToString::operator()(char _cell)
{
    stringBoard.push_back(_cell);
    //std::cout << _cell;
    //std::cout << stringBoard.back();
    if (isItLastLine())
    {
        stringBoard.push_back('\n');
        //std::cout << stringBoard.back();
        //std::cout << '\n';
        resetCharsToNewLine();
    }
}

经过一些测试,我很确定当 for_each 结束他的工作时 stringBoard 会被清除。当 for_each 工作时,GDB 显示正确的字符串大小,之后显示为 0。两个评论的 couts 都正常工作。反正我不知道为什么会这样。我知道我可以通过稍微不同的实现来轻松解决它,但我想以正确的方式做到这一点。

【问题讨论】:

标签: c++ string oop foreach stl


【解决方案1】:

改变

std::for_each(v_board.begin(), v_board.end(), boardToString);

std::for_each(v_board.begin(), v_board.end(), std::ref(boardToString));

复制传递给 std 算法的函数对象; std ref 将它们包装起来,因此它们不会被复制。

【讨论】:

    【解决方案2】:

    所以问题是您的仿函数对象正在被复制并且正在对副本进行修改。这就是为什么它似乎在您完成后重置的原因。

    您可以更改仿函数以保存对您需要修改的变量的引用。

    您可以改用 lambda,再次保存对需要修改的变量的引用。

    但对我来说,整个方法太复杂了。只需编写一个 for 循环。没有任何东西被复制,一切都是透明和直接的。

    【讨论】:

    • std ref 是最简单的修复方法;通过std::ref(boardToString).
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-29
    • 1970-01-01
    • 2021-09-25
    • 1970-01-01
    • 2022-01-10
    • 1970-01-01
    相关资源
    最近更新 更多