увеличить пользовательский форматер, используя метод привязки к методу, используя только один параметр - PullRequest
3 голосов
/ 11 ноября 2010

Я пытаюсь использовать boost :: regex_replace с пользовательским форматером.Мне нужно передать метод из объекта, потому что в замещающей функции необходим какой-то член.

Подпись моего замещающего метода:

std::string MyObject::ReplaceStr(
    boost::match_results<std::string::const_iterator> match) const

При вызове regex_replace я передаюэти аргументы:

std::string replaced = regex_replace(
    orig_string, replace_pattern, 
    boost::bind<std::string>(&MyObject::ReplaceStr, this, _1));

Проблема в том, что когда regex_replace вызывает метод форматирования для результата совпадения, используется функтор, принимающий 3 параметра (пользовательский форматировщик может быть строковой, унарной, двоичной или троичной функцией).Я думаю, это связано с тем, что boost :: bind в некоторой степени скрывает арность функции.

Причина, по которой я думаю, что это связано с исчезновением арности, заключается в том, что при связывании с

std::string replaced = regex_replace(
    orig_string, replace_pattern,       
    std::bind1st(std::mem_fun(&MyObject::ReplaceStr), this));

вызывается правильный функтор (тот, который использует унарную функцию).

Возможно, я мог бы также просто использовать троичную функцию в моем объекте для привязки, и тогда это, вероятно, сработало бы, но ради понимания иИспользование boost :: bind может кто-нибудь объяснить, правильно ли я понял, а если нет, предоставить правильное объяснение.

Бонус, если я могу заставить его работать с boost bind.

РЕДАКТИРОВАТЬ: Я забыл сказать, что происходит сбой при использовании boost::bind из-за неправильной подписи метода.Вот фрагмент кода для воспроизведения поведения, которое я пытался объяснить:

using namespace std;
using namespace boost;

class MyObject
{
public:
    void ReplacePattern()
    {
        const std::string testString = "${value_to_replace}extra_value";

        boost::regex replace_pattern("(\\$\\{(.*?)\\})");
        std::string replaced = regex_replace(testString, replace_pattern, boost::bind(&MyObject::ReplaceStr, this, _1));

        cout << "Replaced: " << replaced << endl;
    }

    std::string ReplaceStr(
        boost::match_results<std::string::const_iterator> match) const
    {
        return "replaced_value";
    }
};


int main(int argc, char* argv[])
{
    MyObject obj;
    obj.ReplacePattern();


    char dummy[1];
    cin.getline(dummy, 1);

    return 0;
}

1 Ответ

2 голосов
/ 14 ноября 2010

Вы можете использовать boost :: function, чтобы избежать неоднозначности:

boost::function<std::string (boost::match_results<std::string::const_iterator>)> function =
    boost::bind(&MyObject::ReplaceStr, this, _1);
std::string replaced = regex_replace(testString, replace_pattern, function);
...