2017-06-27 4 views
0

私は関数を持っています:std::string format(const std::string sformat, ...); これは基本的にはsprintf()のように機能します。'const std :: string&'の後の変数引数リストはスタックを壊す

私はその関数を多く呼び出すので、書式文字列をref:const std::string& sformatとして渡したいと思っていました。 残念ながら、va_start()は可変引数リストにスタック上の正しい場所を見つけるのに問題があるようです。

「&」を削除しても問題ありません。

つの質問:A:私も通話中にsformatのコピーを防止するために、参照を必要とする、または単にバックグラウンドでパス・バイ・参照を行うのに十分賢いオプティマイザですか? B:フォーマット文字列の値渡しを防ぎ、まだva_start()を混同しないようにするにはどうすればよいですか?

私の推測です:パスバイポインター。または、より良い解決策がありますか?ボーナスとして

+5

「またはもっと良い解決策がありますか?」可変長パックを削除して可変長テンプレートを使用する方法はありますか? – Rakete1111

+1

これはコンパイラ固有のものなので、使用しているコンパイラを教えてください。どのバージョン?あなたはどのシステムをターゲットにしていますか? –

+6

[variadic template](http://en.cppreference.com/w/cpp/language/parameter_pack)を使用しますか? – NathanOliver

答えて

0
namespace details { 
    std::string format(char const* sformat, ...) { 
    // code 
    } 
} 
template<class...Args> 
std::string format(std::string const& str, Args const&... args) { 
    return details::format(str.data(), args...); 
} 

、私はto_podヘルパー書くことができます。

namespace details { 
    std::string format(char const* sformat, ...) { 
    // code 
    } 
} 
template<class T> 
T const& to_pod(T const& t){ return t; } 
template<class Char, class Attribs> 
Char const* to_pod(std::basic_string<Char, Attribs> const& str) { 
    return t.data(); 
} 
template<class...Args> 
std::string format(std::string const& str, Args const&... args) { 
    return details::format(str.data(), to_pod(args)...); 
} 

を、今私は、最初の引数を過ぎてのものとしてstd::string Sを渡すことができ、そして、彼らはへchar const*ポインタに自動変換され、バッファ。

...

あなたは(MSVC 2010と言う)C++ 11コンパイラを持っていない場合は、あなたの最善の策は、単にオーバーロードを書くことが考えられます。

std::string format(std::string const& str) { 
    return details::format(str.data()); 
} 
template<class A0> 
std::string format(std::string const& str, A0 const& a0) { 
    return details::format(str.data(), to_pod(a0)); 
} 
template<class A0, class A1> 
std::string format(std::string const& str, A0 const& a0, A1 const& a1) { 
    return details::format(str.data(), to_pod(a0), to_pod(a1)); 
} 
// etc 

おそらく10個を超える引数が必要です。

+0

これは現在のコンパイラのための良い解決策であるため、これを解決策としてマークします。 – MrTridac

+0

私の最後のコメントに加えて:残念ながら、私は使用する必要があるコンパイラは、variadicテンプレートを知らない。だから、私は複数のオーバーロードやポインタバイパスをするつもりです。 – MrTridac

関連する問題