这是执行此模板的正确方法吗? [英] Is this the correct way to do this template?

查看:65
本文介绍了这是执行此模板的正确方法吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个模板我称之为StrmConvert,它使用std :: stringstream来将
从任何类型转换为stringstring可以使用的任何其他类型。

它是什么样的:


模板< typename T,typename F> T StrmConvert(F from)

{

std :: stringstream temp;

temp<< from;

T to = T();

temp>> to;

返回;

}


它对我来说效果很好,但我觉得它可以打字很多。我把它放在名为jml的名为
的命名空间中,所以我最终做了这样的事情:


std :: cout<< jml :: StrmConvert< std :: string>(floatvalue);


我发现99%的时间我正在转换为std :: string所以我已经决定了以这种方式专门化它(如果这是正确的术语):


模板< typename F> std :: string StrmConvert(F from)

{

返回StrmConvert< std :: string>(from);

}


它似乎有效。现在我可以说:


std :: cout<< jml :: StrmConvert(floatvalue);


因为如果我没有指定typename,则使用std :: string。这是

正确的方法吗?它似乎工作,但我想知道是否有任何问题可以解决这个问题。我做了这个测试并且它有效,我只是一个n00b

模板。


#include< string>

#include< iostream>

#include< sstream>


模板< typename T,typename F> T StrmConvert(F from)

{

std :: stringstream temp;

temp<< from;

T to = T();

temp>> to;

返回;

}


模板< typename F> std :: string StrmConvert(F from)

{

返回StrmConvert< std :: string>(from);

}


int main()

{


std :: cout<< StrmConvert< std :: string>(123.45)<< std :: endl;

std :: cout<< StrmConvert(123.45)<< std :: endl;


float MyValue = StrmConvert< float>(" 123.456");

std :: cout<< MyValue<< std :: endl;


std :: string wait;

std :: cin>>等待;

}

I have a template I call StrmConvert, which uses std::stringstream to
convert from any type to any other type that can be used by stringstring.
This is what it looks like:

template<typename T, typename F > T StrmConvert( F from )
{
std::stringstream temp;
temp << from;
T to = T();
temp >> to;
return to;
}

it works well for me, but I find it can be a lot of typing. I have it in a
namespace called jml so I wind up doing things like this:

std::cout << jml::StrmConvert<std::string>( floatvalue );

I find that 99% of the time I''m converting to std::string so I''ve decided to
specialize it (if that is the right term) this way:

template<typename F> std::string StrmConvert( F from )
{
return StrmConvert<std::string>( from );
}

and it seems to work. Now I can say:

std::cout << jml::StrmConvert( floatvalue );

because if I don''t specify the typename T is uses the std::string. Is this
the right way to do it? It seems to work, but I want to know if there can
be any problems with this. I did this test and it works, I''m just a n00b
when it comes to templates.

#include <string>
#include <iostream>
#include <sstream>

template<typename T, typename F > T StrmConvert( F from )
{
std::stringstream temp;
temp << from;
T to = T();
temp >> to;
return to;
}

template<typename F> std::string StrmConvert( F from )
{
return StrmConvert<std::string>( from );
}

int main ()
{

std::cout << StrmConvert<std::string>( 123.45 ) << std::endl;
std::cout << StrmConvert( 123.45 ) << std::endl;

float MyValue = StrmConvert<float>( "123.456" );
std::cout << MyValue << std::endl;

std::string wait;
std::cin >> wait;
}

推荐答案

Jim Langston写道:
Jim Langston wrote:
我有一个模板,我称之为StrmConvert,它使用std :: stringstream从任何类型转换为stringstring可以使用的任何其他类型。
这就是它的样子:

模板< typename T,typename F> T StrmConvert(F from)
{
std :: stringstream temp;
temp<< from;
T to = T();
temp>> to;
返回;
}

对我来说效果很好,但我觉得它可以打字很多。我在一个名为jml的命名空间中有它,所以我最终做了这样的事情:

std :: cout<< jml :: StrmConvert< std :: string>(floatvalue);

我发现99%的时间我正在转换为std :: string所以我已经决定了
以这种方式专门化它(如果这是正确的术语):

模板< typename F> std :: string StrmConvert(F from)
{
返回StrmConvert< std :: string>(from);
}

它似乎有效。现在我可以说:

std :: cout<< jml :: StrmConvert(floatvalue);

因为如果我没有指定typename,则使用std :: string。这是
这个正确的方法吗?它似乎有效,但我想知道是否有任何问题。我做了这个测试并且它有效,我只是一个n00b
当谈到模板时。

#include< string>
#include< iostream>
#include< sstream>

模板< typename T,typename F> T StrmConvert(F from)
{
std :: stringstream temp;
temp<< from;
T to = T();


T to;

temp>> to;
返回;
}


此外,如果转换失败,您可能想要扔东西。无论如何,

boost :: lexical_cast可能是你试图在这里重新发明的。

模板< typename F> std :: string StrmConvert(F from)
{
返回StrmConvert< std :: string>(from);
}
int main()
{

std :: cout<< StrmConvert< std :: string>(123.45)<<的std :: ENDL;


我没有看到你买的东西比


std :: cout<< 123.45<< std :: endl;


另请注意,StrmConvert<>关于浮动类型是坏的:

转换甚至不会远程进行往返:


double x;

double y = StrmConvert< double>(x);


这会将y转换成6位数的精确近似值(我认为<<有一个

默认精度就像那样)。通常这不是你想要的。


另请注意运营商<<和运算符>>对于某些其他类型(例如,std :: string)而言,并非严格的反转。你的演员阵容可能会带来令人惊讶的结果。

std :: cout<< StrmConvert(123.45)<< std :: endl;

float MyValue = StrmConvert< float>(" 123.456");
std :: cout<< MyValue<< std :: endl;

std :: string wait;
std :: cin>>等待;
}
I have a template I call StrmConvert, which uses std::stringstream to
convert from any type to any other type that can be used by stringstring.
This is what it looks like:

template<typename T, typename F > T StrmConvert( F from )
{
std::stringstream temp;
temp << from;
T to = T();
temp >> to;
return to;
}

it works well for me, but I find it can be a lot of typing. I have it in
a namespace called jml so I wind up doing things like this:

std::cout << jml::StrmConvert<std::string>( floatvalue );

I find that 99% of the time I''m converting to std::string so I''ve decided
to specialize it (if that is the right term) this way:

template<typename F> std::string StrmConvert( F from )
{
return StrmConvert<std::string>( from );
}

and it seems to work. Now I can say:

std::cout << jml::StrmConvert( floatvalue );

because if I don''t specify the typename T is uses the std::string. Is
this
the right way to do it? It seems to work, but I want to know if there can
be any problems with this. I did this test and it works, I''m just a n00b
when it comes to templates.

#include <string>
#include <iostream>
#include <sstream>

template<typename T, typename F > T StrmConvert( F from )
{
std::stringstream temp;
temp << from;
T to = T();
T to;
temp >> to;
return to;
}
Also, you may want to throw something if the conversion fails. Anyhow,
boost::lexical_cast is maybe what you try to reinvent here.

template<typename F> std::string StrmConvert( F from )
{
return StrmConvert<std::string>( from );
}

int main ()
{

std::cout << StrmConvert<std::string>( 123.45 ) << std::endl;
I fail to see what that buys you compared to

std::cout << 123.45 << std::endl;

Also note that the StrmConvert<> is broken with regard to float types:
conversion will not even remotely make a round-trip:

double x;
double y = StrmConvert<double>( x );

This will turn y into a 6-digit precission approximation (I think << has a
default precision like that). Usually that is not what you want.

Also note that operator<< and operator>> are not strict inverses for some
other types (e.g., std::string). Your cast may lead to surprising results.
std::cout << StrmConvert( 123.45 ) << std::endl;

float MyValue = StrmConvert<float>( "123.456" );
std::cout << MyValue << std::endl;

std::string wait;
std::cin >> wait;
}



Best


Kai-Uwe Bux


Best

Kai-Uwe Bux


Kai-Uwe Bux < JK ******** @ gmx.net>在消息中写道

新闻:12 ************* @ corp.supernews.com ...
"Kai-Uwe Bux" <jk********@gmx.net> wrote in message
news:12*************@corp.supernews.com...
Jim Langston写道:
Jim Langston wrote:
我有一个模板,我称之为StrmConvert,它使用std :: stringstream从任何类型转换为stringstring可以使用的任何其他类型。
这是它看起来像:

模板< typename T,typename F> T StrmConvert(F from)
{
std :: stringstream temp;
temp<< from;
T to = T();
temp>> to;
返回;
}

对我来说效果很好,但我觉得它可以打字很多。我在一个名为jml的命名空间中有它,所以我最终做了这样的事情:

std :: cout<< jml :: StrmConvert< std :: string>(floatvalue);

我发现99%的时间我正在转换为std :: string所以我已经决定了
以这种方式专门化它(如果这是正确的术语):

模板< typename F> std :: string StrmConvert(F from)
{
返回StrmConvert< std :: string>(from);
}

它似乎有效。现在我可以说:

std :: cout<< jml :: StrmConvert(floatvalue);

因为如果我没有指定typename,则使用std :: string。这是
这个正确的方法吗?它似乎工作,但我想知道是否有
可以对此有任何问题。我做了这个测试并且它有效,我只是一个n00b
当谈到模板时。

#include< string>
#include< iostream>
#include< sstream>

模板< typename T,typename F> T StrmConvert(F from)
{
std :: stringstream temp;
temp<< from;
T to = T();
T to;
I have a template I call StrmConvert, which uses std::stringstream to
convert from any type to any other type that can be used by stringstring.
This is what it looks like:

template<typename T, typename F > T StrmConvert( F from )
{
std::stringstream temp;
temp << from;
T to = T();
temp >> to;
return to;
}

it works well for me, but I find it can be a lot of typing. I have it in
a namespace called jml so I wind up doing things like this:

std::cout << jml::StrmConvert<std::string>( floatvalue );

I find that 99% of the time I''m converting to std::string so I''ve decided
to specialize it (if that is the right term) this way:

template<typename F> std::string StrmConvert( F from )
{
return StrmConvert<std::string>( from );
}

and it seems to work. Now I can say:

std::cout << jml::StrmConvert( floatvalue );

because if I don''t specify the typename T is uses the std::string. Is
this
the right way to do it? It seems to work, but I want to know if there
can
be any problems with this. I did this test and it works, I''m just a n00b
when it comes to templates.

#include <string>
#include <iostream>
#include <sstream>

template<typename T, typename F > T StrmConvert( F from )
{
std::stringstream temp;
temp << from;
T to = T();
T to;
temp>> to;
返回;
}
temp >> to;
return to;
}



此外,如果转换失败,您可能想要扔东西。



Also, you may want to throw something if the conversion fails.



我已经考虑过扔了,但是每次我使用时都需要抓住

StrmConvert,这很多。我宁愿采用默认值

是什么T();应该给我。如果有一个我想知道的情况

如果这是一个不好的价值,我会在模板之前测试它之前我会把它称为

或之后。

无论如何,
boost :: lexical_cast可能是你试图在这里重新发明的东西。


最有可能。我只是不使用,但一旦它成为标准的一部分,我将

将。



I''ve thought about throwing, but then I would need to catch every time I use
StrmConvert, which is a lot. I would rather take the default value which is
what the T(); should be giving me. If there is a case where I want to know
if it''s a bad value, I''ll test for it outside the template before I call it
or after.
Anyhow,
boost::lexical_cast is maybe what you try to reinvent here.
Most likely. I just don''t use, but once it becomes part of the standard I
will.

template< typename F> std :: string StrmConvert(F from)
{
返回StrmConvert< std :: string>(from);
}
int main()
{

std :: cout<< StrmConvert< std :: string>(123.45)<< std :: endl;
template<typename F> std::string StrmConvert( F from )
{
return StrmConvert<std::string>( from );
}

int main ()
{

std::cout << StrmConvert<std::string>( 123.45 ) << std::endl;





std :: cout<<相比,我看不到你买的东西了123.45<< std :: endl;



I fail to see what that buys you compared to

std::cout << 123.45 << std::endl;




好​​吧,通常这会用于使用图形调用输出文本。

类似于:

draw_text(x,y,"值为:" + jml :: StrmConvert(HPs));


这里的std :: cout刚刚完成对于我的测试,因为它没有给我任何东西

带来我的所有图形代码进行测试。

另请注意StrmConvert<>关于浮点类型是否被打破:
转换甚至不会远程进行往返:

double x;
double y = StrmConvert< double>(x); <这将把y变成一个6位数的精确近似(我认为<<<<>具有这样的默认精度)。通常这不是你想要的。


幸运的是,这通常是我想要的。正如我所说,这通常是用于简单输出的
。很明显,如果我确实需要精确度,那么无论如何

我可以解决它吗?

另请注意运营商<<和运算符>>对于某些其他类型(例如,std :: string),并不是严格的反转。你的演员表可能会产生令人惊讶的结果。



Well, usually this would be used for outputing text using a graphical call.
Something like:
draw_text( x, y, "The value is: " + jml::StrmConvert( HPs ) );

The std::cout here was just done for my test since it gained me nothing to
bring in all my graphical code for a test.
Also note that the StrmConvert<> is broken with regard to float types:
conversion will not even remotely make a round-trip:

double x;
double y = StrmConvert<double>( x );

This will turn y into a 6-digit precission approximation (I think << has a
default precision like that). Usually that is not what you want.
Luckily for me, this is usually what I want. As I said, this is normally
used for simple output. Incidently, if I do need precision, is there anyway
I can fix it?
Also note that operator<< and operator>> are not strict inverses for some
other types (e.g., std::string). Your cast may lead to surprising results.




请解释一下?我不明白你在这说什么。



Please explain? I don''t understand what you''re saying here.

std :: cout<< StrmConvert(123.45)<< std :: endl;

float MyValue = StrmConvert< float>(" 123.456");
std :: cout<< MyValue<< std :: endl;

std :: string wait;
std :: cin>>等待;
}
std::cout << StrmConvert( 123.45 ) << std::endl;

float MyValue = StrmConvert<float>( "123.456" );
std::cout << MyValue << std::endl;

std::string wait;
std::cin >> wait;
}




感谢代码讽刺。



Thanks for the code revue.


Jim Langston写道:
Jim Langston wrote:
" Kai-Uwe Bux" < JK ******** @ gmx.net>在消息中写道
新闻:12 ************* @ corp.supernews.com ...
"Kai-Uwe Bux" <jk********@gmx.net> wrote in message
news:12*************@corp.supernews.com...
Jim Langston写道:
Jim Langston wrote:
我有一个模板,我称之为StrmConvert,它使用std :: stringstream从任何类型转换为
stringstring可以使用的任何其他类型。这就是它的样子:

模板< typename T,typename F> T StrmConvert(F from)
{
std :: stringstream temp;
temp<< from;
T to = T();
temp>> to;
返回;
}
[snip] int main()

std :: cout<< StrmConvert< std :: string>(123.45)<< std :: endl;


std :: cout<<相比,我看不到你买的东西了123.45<< std :: endl;
I have a template I call StrmConvert, which uses std::stringstream to
convert from any type to any other type that can be used by
stringstring. This is what it looks like:

template<typename T, typename F > T StrmConvert( F from )
{
std::stringstream temp;
temp << from;
T to = T();
temp >> to;
return to;
} [snip] int main ()
{

std::cout << StrmConvert<std::string>( 123.45 ) << std::endl;
I fail to see what that buys you compared to

std::cout << 123.45 << std::endl;



嗯,通常这将用于使用图形
调用输出文本。类似的东西:
draw_text(x,y,"值是:" + jml :: StrmConvert(HPs));

这里的std :: cout刚刚为我完成了测试,因为它没有给我任何东西来引入我的所有图形代码进行测试。



Well, usually this would be used for outputing text using a graphical
call. Something like:
draw_text( x, y, "The value is: " + jml::StrmConvert( HPs ) );

The std::cout here was just done for my test since it gained me nothing to
bring in all my graphical code for a test.

还要注意StrmConvert<>关于浮点类型是否被打破:
转换甚至不会远程进行往返:

double x;
double y = StrmConvert< double>(x); <这将把y变成一个6位数的精确近似(我认为<<<具有这样的默认精度)。通常这不是你想要的。
Also note that the StrmConvert<> is broken with regard to float types:
conversion will not even remotely make a round-trip:

double x;
double y = StrmConvert<double>( x );

This will turn y into a 6-digit precission approximation (I think << has
a default precision like that). Usually that is not what you want.



幸运的是,这通常是我想要的。正如我所说,这通常用于简单的输出。很明显,如果我确实需要精确度,是否还有
我可以解决它?



Luckily for me, this is usually what I want. As I said, this is normally
used for simple output. Incidently, if I do need precision, is there
anyway I can fix it?




是的,您需要将stringstream的精度设置为对吧

值。您可以让模板根据浮动

类型(部分特化)执行该操作,或者将精度参数作为第二个
参数传递,并将其默认为合理的。



Yes, you would need to set the precision of the stringstream to the right
value. You could either have the template do that based upon the floating
type (partial specialization) or you pass a precision parameter as a second
argument and have it default to something reasonable.

还要注意运算符<<和运算符>>对于某些其他类型(例如,std :: string),并不是严格的反转。你的演员阵容可能会导致惊人的结果。
Also note that operator<< and operator>> are not strict inverses for some
other types (e.g., std::string). Your cast may lead to surprising
results.



请解释一下?我不明白你在这说什么。



Please explain? I don''t understand what you''re saying here.




好​​吧,我把你的模板误认为是演员。所以我关注的代码如下:


std :: string s =" hello world!" ;;

std :: string t = my_fancy_cast< std :: string>(s);


现在,给定天真的字符串流实现,字符串t将

为hello而不是hello world!。


现在我知道你只想转换为std :: string,这样你就可以输出任何东西通过一些带字符串或C字符串的API,


模板< typename T>

std :: string any_to_string(T const& obj){

std :: stringstream dummy;

if(! (dummy<< obj)){

throw(std :: runtime_error(转换为字符串失败));

}

返回dummy.str();

}


或:


template< typename T>

std :: string any_to_string(T const& obj,unsigned short prec = 6){

std :: stringstream dummy;

if(!(dummy<< std :: setprecision(prec)<< obj)){

throw(std :: runtime_error("转换为字符串失败)") );

}

返回dummy.str();

}

最佳


Kai-Uwe Bux



Well, I mistook your template for a cast. So I was concerned with code like:

std::string s = "hello world!";
std::string t = my_fancy_cast< std::string >( s );

Now, given the naive stringstream implementation, the string t will
be "hello" and not "hello world!".

Now that I know you just want to convert to std::string so that you can
output anything via some API that takes strings or C-Strings, what about:

template< typename T >
std::string any_to_string ( T const & obj ) {
std::stringstream dummy;
if ( !( dummy << obj ) ) {
throw( std::runtime_error( "conversion to string failed" ) );
}
return dummy.str();
}

or:

template< typename T >
std::string any_to_string ( T const & obj, unsigned short prec = 6 ) {
std::stringstream dummy;
if ( !( dummy << std::setprecision(prec) << obj ) ) {
throw( std::runtime_error( "conversion to string failed" ) );
}
return dummy.str();
}
Best

Kai-Uwe Bux


这篇关于这是执行此模板的正确方法吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆