2017-03-16 9 views
3

私はfmt(http://fmtlib.net/latest/)という書式設定ライブラリを使用します。initializer_listをvariadicテンプレートに変換する

可能な用途の一つは次のとおりです。

ため
myFunction(myString, {"name", "World"}, {"number", 42}); 

引数のいずれかの数:私は私のように呼びたい関数の中で、この呼び出しをラップしたい

fmt::format("Hello, {name}! The answer is {number}. Goodbye, {name}.", fmt::arg("name", "World"), fmt::arg("number", 42)); 

myFunction(myString, std::make_pair("name", "World"), std::make_pair("number", 42)); 

機能付:

は今まで、私は唯一のペアのリストで、機能callabelを行うことに成功した

std::string myFunction(const char* str, const Args&... rest) const 
{ 
    return fmt::format(mLocale.getPOILabel(label), fmt::arg(rest.first, rest.second)...); 
} 

が、私は使用のペアを持っていないたい。

どうすればよいですか?

PS:機能間でfmt::argを渡すことはできません。

+1

'テンプレート arg(const char * name、T &&値)'と '{" number "、42}'は、統一された初期化構文を使用して、クラスを作成し、それを構築します。しかし、私は 'arg'のバリデーショナルなリストを取る関数を定義する方法を考えることはできません。パラメータパックのように見えます。 –

+0

あなたのPS *は 'fmt :: format'に渡すとtrue *になることはできません。私はそれがrvalueの参照だけでそれらを受け取ることを期待する – Caleth

答えて

0

const参照をコピーまたは渡すのではなく、fmt :: argの結果を移動してみてください。あなたは

myFunction(myString, "name", "World", "number", 42); 

代わりの

myFunction(myString, {"name", "World"}, {"number", 42}); 

としてあなたの関数を呼び出す必要がありますが、一例である必要があり、次の(申し訳ありませんが、baz()があるので

template<typename ... Args> 
std::string myFunction(const char* str, Args&&... rest) const 
{ 
    return fmt::format(mLocale.getPOILabel(label), std::forward<Args...>(rest)...); 
} 

myFunction(myString, fmt::arg("name", "World"), fmt::arg("number", 42)); 
0

あなたは、尋ねない、まさに未試験)

#include <tuple> 
#include <string> 
#include <utility> 
#include <iostream> 

// fmt headers 

template <typename ... Ps> 
std::string baz (char const * frmt, 
       std::pair<char const *, Ps> const & ... ps) 
{ return fmt::format(frmt, fmt::arg(ps.first, ps.second)...); } 

template <typename ... Ts, std::size_t ... Is> 
std::string bar (char const * frmt, std::tuple<Ts...> const & t, 
       std::index_sequence<Is...> const &) 
{ return baz(frmt, std::get<Is>(t)...); } 

template <typename ... Ts> 
std::string foo (char const * frmt, std::tuple<Ts...> const & t) 
{ return bar(frmt, t, std::make_index_sequence<sizeof...(Ts)>{}); } 

template <typename ... Ts, typename P1, typename P2, typename ... Args> 
std::string foo (char const * frmt, std::tuple<Ts...> const & t, 
       P1 const & p1, P2 const & p2, Args const & ... args) 
{ return foo(frmt, 
     std::tuple_cat(t, std::make_tuple(std::make_pair(p1, p2))), args...); } 

template <typename ... Args> 
std::string myFunction (char const * frmt, Args const & ... args) 
{ return foo(frmt, std::tuple<>{}, args...); } 

int main() 
{ 
    myFunction("format", "name", "World", "number", 42); 
} 

この例ではstd::index_sequencestd::make_index_sequence()を使用するので、C++ 14からコンパイルしてください。このクラスとこの関数の代わりにC++ 11を使用するのは簡単です。

関連する問題