我想让程序读取类似以下的字符串:
integer_value 1
double_value 1.0
string_value one
我实现以下功能以阅读这些功能:
void read_val_int(
std::vector<std::string> str_vec,
std::string str,
int& val){
if(str_vec[0]==str) val= std::stoi(str_vec[1]);
}
void read_val_dbl(
std::vector<std::string> str_vec,
std::string str,
double& val){
if(str_vec[0]==str) val= std::stoi(str_vec[1]);
}
void read_val_str(
std::vector<std::string> str_vec,
std::string str,
std::string& val){
if(str_vec[0]==str) val= str_vec[1];
}
str_vec
是一个包含两个字符串值的向量,例如{“ integer_value”,“ 1”}。
str
包含一个我想与str_vec[0]
比较的字符串
val
是一个整数,双精度或字符串,如果str_vec[1]
为真,则对应于str_vec[0]==str
。
我将这些功能用作read_val_int(my_str_vec,"integer_value",my_int_val)
。
我的问题是:有没有一种方法可以使用单个函数来执行此操作?我尝试使用模板,但是由于我需要引用val
,因此这似乎是不可能的。
注意:我知道this post,但它在C语言中,对我来说有点混乱。也许有一种更简单的方法可以在C ++中实现。
答案 0 :(得分:2)
如果您在C ++ 17之前,因此无法使用std::variant
,则只能使用模板来使用一个功能。
您对函数进行如下声明:
template <typename T>
void read_val(const std::string & data, T & val);
然后您将其专门用于三种类型:
template <>
void read_val<int>(const std::string & data, int & val)
{
val = std::stoi(data);
}
template <>
void read_val<double>(const std::string & data, double & val)
{
val = std::stod(data);
}
template <>
void read_val<std::string>(const std::string & data, std::string & val)
{
val = data;
}
工作完成后,您可以通过调用只有一个函数来使用三种类型的函数:read_val()
。
您可以按以下方式使用它:
std::string data_int("5");
std::string data_double("2.5");
std::string data_string("Hello");
int int_val;
double double_val;
std::string string_val;
read_val(data_int, int_val);
read_val(data_double, double_val);
read_val(data_string, string_val);
std::cout << int_val << std::endl;
std::cout << double_val << std::endl;
std::cout << string_val << std::endl;
如您所见,通过使用模板专业化,可以将相同的函数用于不同的类型。
此外,它将自动确保您传递了允许的类型。确实,如果您给函数赋予int
,double
或std::string
之外的其他东西,则编译将失败,因为它没有专门的功能。
希望对您有帮助。
答案 1 :(得分:1)
如Dave的注释中所建议,您应该检查变量的类型,以分析向量的第一个元素。 在if-else链中,您可以使用正确的变量类型来满足您的需求。
您还可以使用单个函数使用std :: variant e返回值,然后使用c ++ 17 std :: visit打印值(或执行所需的任何操作)。
可能是这样的:
#include <vector>
#include <string>
#include <variant>
#include <iostream>
using my_variant = std::variant<int, double, std::string>;
my_variant read_val(
const std::vector<std::string> &str_vec)
{
if(str_vec[0]=="integer_value")
{
return std::stoi(str_vec[1]);
}
else if(str_vec[0]=="double_value")
{
return std::stod(str_vec[1]);
}
else if(str_vec[0]=="string_value")
{
return str_vec[1];
}
//notify error in some way, maybe throw
}
void print_variant(const my_variant &v)
{
std::visit([](my_variant &&var)
{
if (std::holds_alternative<int>(var))
std::cout<<"int->"<<std::get<int>(var)<<"\n";
else if (std::holds_alternative<double>(var))
std::cout<<"double->"<<std::get<double>(var)<<"\n";
else if (std::holds_alternative<std::string>(var))
std::cout<<"string->"<<std::get<std::string>(var)<<"\n";
}, v);
}
int main()
{
std::vector<std::string> vec_int {"integer_value", "1"};
std::vector<std::string> vec_dbl {"double_value", "1.5"};
std::vector<std::string> vec_str {"string_value", "str"};
print_variant(read_val(vec_int));
print_variant(read_val(vec_dbl));
print_variant(read_val(vec_str));
return 0;
}