Fer*_*eak 22 c++ stringstream string-conversion c++11
现在我用下面的一段代码dummily转换基本类型(int
,long
,char[]
,这种东西),以std::string
进行进一步的处理:
template<class T>
constexpr std::string stringify(const T& t)
{
std::stringstream ss;
ss << t;
return ss.str();
}
Run Code Online (Sandbox Code Playgroud)
但是我不喜欢它依赖的事实std::stringstream
.我尝试使用std::to_string
(来自C++ 11的保留节目)然而它会扼杀char[]
变量.
有一种简单的方法可以为这个问题提供优雅的解决方案吗?
cer*_*wny 10
据我所知,这样做的唯一方法是通过SFINAE参数类型对模板进行专门化.
您需要包含type_traits.
所以代替你的代码使用这样的东西:
template<class T>
typename std::enable_if<std::is_fundamental<T>::value, std::string>::type stringify(const T& t)
{
return std::to_string(t);
}
template<class T>
typename std::enable_if<!std::is_fundamental<T>::value, std::string>::type stringify(const T& t)
{
return std::string(t);
}
Run Code Online (Sandbox Code Playgroud)
这个测试对我有用:
int main()
{
std::cout << stringify(3.0f);
std::cout << stringify("Asdf");
}
Run Code Online (Sandbox Code Playgroud)
重要说明:传递给此函数的char数组需要以null结尾!
如yakk的评论中所述,您可以通过以下方式摆脱空终止:
template<size_t N> std::string stringify( char(const& s)[N] ) {
if (N && !s[N-1]) return {s, s+N-1};
else return {s, s+N};
}
Run Code Online (Sandbox Code Playgroud)
有一种简单的方法可以为这个问题提供优雅的解决方案吗?
由于没有人提出它,考虑使用boost :: lexical_cast.
这与实现std :: ostream << operator的任何内容无缝集成,并且可以扩展为自定义类型.
我建议使用enable_if_t
,如果你要接受任何单个字符变量,你会专注于那些:
template<typename T>
enable_if_t<is_arithmetic<T>::value, string> stringify(T t){
return to_string(t);
}
template<typename T>
enable_if_t<!is_arithmetic<T>::value, string> stringify(T t){
return static_cast<ostringstream&>(ostringstream() << t).str();
}
template<>
string stringify<char>(char t){
return string(1, t);
}
Run Code Online (Sandbox Code Playgroud)
在这里,我只是专攻char
.如果您需要专业化wchar
,char16
或者char32
您也需要这样做.
无论如何对于非算术类型,这些重载将默认使用ostringstream
,如果你已经为你的一个类重载了它将处理它的提取操作符,那么这是很好的原因.
对于算术类型,这将使用to_string
,除了char
你重载的任何其他东西,那些可以直接创建一个string
.
编辑:
Dyp建议使用是否to_string
接受T::type
作为我enable_if_t
条件的参数.
如果你要访问的最简单的办法是只提供给你is_detected
在#include <experimental/type_traits>
.如果您只是定义:
template<typename T>
using to_string_t = decltype(to_string(declval<T>()));
Run Code Online (Sandbox Code Playgroud)
然后,您可以将代码设置为:
template<typename T>
decltype(to_string(T{})) stringify(T t){
return to_string(t);
}
template<typename T>
enable_if_t<!experimental::is_detected<to_string_t, T>::value, string> (T t){
return static_cast<ostringstream&>(ostringstream() << t).str();
}
template<>
string stringify<char>(char t){
return string(1, t);
}
Run Code Online (Sandbox Code Playgroud)
我问这个问题,弄清楚如何使用to_string
我的条件.如果您无法访问is_detected
我强烈建议您阅读一些答案,因为它们非常现象:元编程:函数定义失败定义了单独的函数
虽然问题不是给我代码类型,但因为我已经实现了一个解决方案,所以我想分享它:
template <class... Tail>
inline auto buildString(std::string const &head, Tail const &... tail)
-> std::string;
template <class... Tail>
inline auto buildString(char const *head, Tail const &... tail) -> std::string;
template <class... Tail>
inline auto buildString(char *head, Tail const &... tail) -> std::string;
template <class Head, class... Tail>
inline auto buildString(Head const &head, Tail const &... tail) -> std::string;
inline auto buildString() -> std::string { return {}; }
template <class... Tail>
inline auto buildString(std::string const &head, Tail const &... tail)
-> std::string {
return head + buildString(tail...);
}
template <class... Tail>
inline auto buildString(char const *head, Tail const &... tail) -> std::string {
return std::string{head} + buildString(tail...);
}
template <class... Tail>
inline auto buildString(char *head, Tail const &... tail) -> std::string {
return std::string{head} + buildString(tail...);
}
template <class Head, class... Tail>
inline auto buildString(Head const &head, Tail const &... tail) -> std::string {
return std::to_string(head) + buildString(tail...);
}
Run Code Online (Sandbox Code Playgroud)
用法:
auto gimmeTheString(std::string const &str) -> void {
cout << str << endl;
}
int main() {
std::string cpp_string{"This c++ string"};
char const c_string[] = "this c string";
gimmeTheString(buildString("I have some strings: ", cpp_string, " and ",
c_string, " and some number ", 24));
return 0;
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
4864 次 |
最近记录: |