web-dev-qa-db-ja.com

Boost.Formatと同等のC ++ 11

C++ 11標準のBoost.Formatのようなものはありますか?私は、他のすべてのニーズに対して、より優れたC++ 11オプションでBoostを使用することを回避することができました。

さらに言えば、Boost.Formatは、Python format()の構文にろうそくを持っていません。そのようなものはさらに良いでしょう。

20
Chris Redford

boost-formatに似たものの提案があります。ただし、これはC++ 11またはC++ 14の一部ではなく、文字列のフォーマットに関連するものも追加されていません。

ここでは、最新の提案を見つけることができます。 boost-formatとは対照的に、可変個引数テンプレートに基づいています。

8
nosid

Nosidによって正しく指摘されているように、C++ 11もC++ 14もBoostFormatと同等のものを提供していません。

ただし、可変個引数テンプレートなどのC++ 11機能をオプションで使用する fmtライブラリ は、Pythonのようなformat関数の実装を提供します。

std::string s = fmt::format("I'd rather be {1} than {0}.", "right", "happy");

*printf関数の安全な代替手段:

fmt::printf("The answer is %d\n", 42);

免責事項:私はこのライブラリの作者です

15
vitaut

C++ 11正規表現と可変個引数テンプレートを使用したPythonのようなフォーマット文字列関数の実装。

/**
   Helper code to unpack variadic arguments
*/
namespace internal
{
    template<typename T>
    void unpack(std::vector<std::string> &vbuf, T t)
    {
        std::stringstream buf;
        buf << t;
        vbuf.Push_back(buf.str());
    }
    template<typename T, typename ...Args>
    void unpack(std::vector<std::string> &vbuf, T t, Args &&... args)
    {
        std::stringstream buf;
        buf << t;
        vbuf.Push_back(buf.str());
        unpack(vbuf, std::forward<Args>(args)...);
    }
}

/**
    Python-like string formatting
 */
template<typename ... Args>
std::string format(const std::string& fmt, Args ... args)
{
    std::vector<std::string> vbuf;  // store arguments as strings
    std::string in(fmt), out;    // unformatted and formatted strings
    std::regex re_arg("\\{\\b\\d+\\b\\}");  // search for {0}, {1}, ...
    std::regex re_idx("\\b\\d+\\b");        // search for 0, 1, ...
    std::smatch m_arg, m_idx;               // store matches
    size_t idx = 0;                         // index of argument inside {...}

    // Unpack arguments and store them in vbuf
    internal::unpack(vbuf, std::forward<Args>(args)...);

    // Replace all {x} with vbuf[x]
    while (std::regex_search(in, m_arg, re_arg)) {
        out += m_arg.prefix();
        if (std::regex_search(m_arg[0].str(), m_idx, re_idx)) {
            idx = std::stoi(m_idx[0].str());
        }
        if(idx < vbuf.size()) {
            out += std::regex_replace(m_arg[0].str(), re_arg, vbuf[idx]);
        }
        in = m_arg.suffix();
    }
    out += in;
    return out;
}

例: cpp.sh/6nli

1
galarius