防止循环内外的代码重复

Preventing code duplication in and outside of a loop

本文关键字:代码 循环      更新时间:2023-10-16

我有一个问题重写循环:

else if( "d" == option || "debug" == option )
{
    debug(debug::always) << "commandline::set_internal_option::setting debug options: "
                         << value << ".n";
    string::size_type index = 0;
    do
    {
        const string::size_type previous_index = index+1;
        index=value.find( ',', index );
        const string item = value.substr(previous_index, index);
        debug::type item_enum;
        if( !map_value(lib::debug_map, item, item_enum) )
            throw lib::commandline_error( "Unknown debug type: " + item, argument_number );
        debug(debug::always) << "commandline::set_internal_option::enabling " << item
                             << " debug output.n";
        debug(debug::always) << "n-->s_level=" << debug::s_level << "n";
        debug::s_level = static_cast<debug::type>(debug::s_level ^ item_enum);
        debug(debug::always) << "n-->s_level=" << debug::s_level << "n";
    } while( index != string::npos );
}

value类似于string("commandline,parser"),问题是在第一次运行时,我需要substr(previous_index, index),但在随后的每次迭代中,我需要substr(previous_index+1, index)跳过逗号。是否有一些我忽略的简单方法,或者我必须在初始迭代的循环之外重复对find的调用?

既然您的目标是防止代码重复:

std::vector<std::string> v;
boost::split(v, value, [](char c) { c == ','; });

如果你想创建自己的split函数,你可以这样做:

template<typename PredicateT>
std::vector<std::string> Split(const std::string & in, PredicateT p)
{
    std::vector<std::string> v;
    auto b = in.begin();
    auto e = b;
    do {
        e = std::find_if(b, in.end(), p);
        v.emplace_back(b,e);
        b = e + 1;        
    } while (e != in.end());
    return v;
}

substr后为什么不更新previous_index呢?

string::size_type index = 0;
string::size_type previous_index = 0;
do {
  index=value.find( ',', previous_index );
  const string item = value.substr(previous_index, index);
  previous_index = index+1;
} while( index != string::npos );

未选中,但这应该可以达到目的(只需要多一个单词的内存)。

-1开始?

string::size_type index = -1;
do
{
    const string::size_type previous_index = index + 1;
    index=value.find(',', previous_index);
    const string item = value.substr(previous_index, index - previous_index);
} while( index != string::npos );

一个愚蠢的(有点难以读懂的)解决方案是这样的:

string::size_type once = 0;
/* ... */
const string::size_type previous_index = index+1 + (once++ != 0); // or !!once

首先,我认为有一个小错误:

在你的代码中,表达式index=value.find( ',', index );不会改变index的值,如果它已经是字符串中逗号字符的索引(除了第一次循环迭代之外,总是这种情况)。

所以你可能想用while( index++ != string::npos );代替while( index != string::npos );,用previous_index = index代替previous_index = index+1

这应该也能解决你原来的问题。

澄清:

string::size_type index = 0;
do
{
    const string::size_type previous_index = index;
    index = value.find( ',', index );
    const string item = value.substr(previous_index, index - previous_index);
} while( index++ != string::npos );