我有一个功能:std::string format(const std::string sformat, ...);
它基本上像一个花哨的sprintf()。
由于我调用了很多函数,我想将格式字符串作为ref:const std::string& sformat
传递。
不幸的是,va_start()似乎在查找堆栈上的正确位置到变量参数列表时遇到了问题。
如果我删除'&'它工作正常。
两个问题: A:我是否甚至需要引用以防止在调用期间发送sformat
副本,或者优化器是否足够聪明才能执行传递-ref在后台?
B:我该怎样做才能阻止格式字符串的传值,仍然不会混淆va_start()?
我的猜测是:传递指针。或者有更好的解决方案吗?
答案 0 :(得分: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
传递给第一个参数,并将它们自动转换为指向缓冲区的char const*
。
...
如果您没有C ++ 11编译器(比如MSVC 2010),那么您最好的选择就是编写重载。
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个参数。