c++ - Why does the string version of this template function compile but the float version doesn't?
问题描述
I don't have much experience with templating in C++, but I know it can be very handy and am trying to use it more.
I created the following example code which does not compile, with the compiler complaining about potentially assigning a string
to a float
on line 19. I think I understand that error, but if I change the instantiation of the template on line 39 from float
s to string
s (so vector<string> scales = line_to_vector<string>("0.0 1.0 2.0 3.0")
), the code compiles and runs correctly. Why does this version not generate a compiler error on line 17, since the string
instantiation would compile that line to assign a float
to a string
?
#include <string>
#include <vector>
#include <iostream>
#include <typeinfo>
using namespace std;
template <class T>
vector< T > line_to_vector(string line, string sep=" ")
{
vector< T > input_set;
size_t pos = line.find(sep);
T buf;
while( pos != string::npos )
{
if(is_same<T, float>::value)
buf = stof(line.substr(0, pos));
else if(is_same<T, string>::value)
buf = line.substr(0, pos);
else
{
cerr << "Can't process line of type " << typeid(T).name()
<< ". Please choose float or string." << endl;
return input_set;
}
input_set.push_back(buf);
if( line.length() )
{
pos = line.find(sep);
line = line.substr(pos+1);
}
}
return input_set;
}
int main()
{
vector<float> scales = line_to_vector<float>("0.0 1.0 2.0 3.0");
for(size_t i=0; i<scales.size(); i++)
cout << scales[i] << ", ";
cout << endl;
return 0;
}
prompt > g++ comp_err.cc
comp_err.cc:19:19: error: assigning to 'float' from incompatible type 'std::__1::basic_string<char>'
buf = line.substr(0, pos);
^~~~~~~~~~~~~~~~~~~
comp_err.cc:39:28: note: in instantiation of function template specialization 'line_to_vector<float>' requested here
vector<float> scales = line_to_vector<float>("0.0 1.0 2.0 3.0");
^
1 error generated.
I can avoid this problem entirely if I just drop the templating (this is a simple-enough situation to not really require it), but I want to understand what is going on here.
解决方案
您似乎在以迂回的方式询问为什么将浮点数分配给字符串没有错误,例如:
#include <string>
int main()
{
std::string x;
x = 5.5f;
}
答案是这会调用赋值运算符重载(此处为 #4):
basic_string& operator=( CharT ch );
存在从float
to的隐式转换char
,行为是将字符串设置为仅包含该字符。
事后看来,这并不是一个伟大的设计决定,而是std::string
在 20 多年前设计的,当时还没有预见到今天的语言演变。
推荐阅读
- c# - 如何在 c# 中访问返回的 json 中的数据?
- apache-spark - 跨多个来源连接的火花 ETL
- embedded - i2c stm8 事件问题
- node.js - Nodejs nodemailer用户名和密码不被接受
- php - WP_Query 在查询中传递术语
- github - 在IDEA中,我将我的项目推送到我的GitHub存储库,但我发现该帐户不是我的,严重不存在,为什么?
- c# - 模拟 EF 核心 dbcontext 和 dbset
- gradle - Gradle 中的全局 Artifactory 配置(带有凭据)
- java - 我的碰撞检测器让我的 Sprite 夹穿过一些墙壁并与其他墙壁发生碰撞,我不知道为什么
- r - 在 fork 集群中的进程之间通信数据(来自 R 包并行)