2014-05-01 22 views
16

Bất cứ thứ gì như Boost.Format trong tiêu chuẩn C++ 11? Tôi đã có thể tránh sử dụng Boost với tùy chọn C++ 11 tốt hơn cho mọi nhu cầu khác mà tôi đã có.C++ 11 Tương đương với Boost.Format

Đối với vấn đề đó, Boost.Format không giữ một ngọn nến theo cú pháp của Python format(). Một cái gì đó như thế sẽ tốt hơn.

+0

Có gì sai với tốt cũ C/K & R xxprintf()? – FoggyDay

+6

Tôi thích nó nói chung nhưng nó không thể chấp nhận 'chuỗi' trực tiếp, đó là gây phiền nhiễu. Tôi thích một phương thức không yêu cầu tôi gọi '.c_str()' trên tất cả các chuỗi của tôi. Thêm vào đó, nó là hư không gần như là tốt đẹp như của Python 'định dạng() '. –

+1

@FoggyDay: Không có loại an toàn. Ở tất cả. Không thể mở rộng. –

Trả lời

7

Có đề xuất cho một cái gì đó tương tự như định dạng tăng. Tuy nhiên, nó không phải là một phần của C++ 11 cũng như C++ 14, và cũng không có bất cứ điều gì liên quan đến định dạng chuỗi được thêm vào.

Tại đây bạn có thể tìm thấy đề xuất mới nhất. Ngược lại với định dạng tăng, dựa trên mẫu variadic.

11

Như một cách chính xác chỉ ra bởi nosid không phải C++ 11 hay C++ 14 cung cấp một tương đương với Tăng Format.

Tuy nhiên, fmt library mà tùy chọn sử dụng C++ 11 tính năng như mẫu variadic cung cấp một thực hiện các Python-như format chức năng:

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

và giải pháp thay thế an toàn để *printf chức năng:

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

Tuyên bố từ chối trách nhiệm: Tôi là tác giả của thư viện này

0

Thực hiện chức năng chuỗi định dạng giống như Python với C++ 11 mẫu regex và variadic.

/** 
    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; 
} 

Ví dụ: cpp.sh/6nli

Các vấn đề liên quan