减少将参数传递给函数所需的字符串流操作的冗长程度
Reduce verbosity of stringstream operations necessary to pass parameters to a function
给定以下代码:
#include <string>
#include <sstream>
int add(int a, int b) {
return a + b;
}
int main() {
std::string str = "1 2";
std::stringstream ss(str);
int a, b;
ss >> a;
ss >> b;
printf("Result: %d\n", add(a, b));
}
我想知道是否有任何方法可以减少此处部分的冗长:
int a, b;
ss >> a;
ss >> b;
printf("Result: %d\n", add(a, b));
并减少添加到类似内容中的调用:
add(ss >> ?, ss >> ?) // ? because I don't know what'd you'd put there.
基本上,把它变成一条线。
你的意思是这样的?
int sum( istream & is ) {
int n, total = 0;
while( is >> n ) {
total += n;
}
return total;
}
您可以创建一个函数
int getInt(std::istream& instr)
{
int n;
instr >> n;
return n;
}
然后使用
printf("Result: %d\n", add(getInt(ss), getInt(ss)));
PS
如果 add
的参数评估顺序很重要,则该方法将不起作用。例如,您不能使用:
printf("Result: %d\n", subtract(getInt(ss), getInt(ss)));
其中 subtract
具有通常的含义。
您当然可以使用:
int a = getInt(ss);
int b = getInt(ss);
printf("Result: %d\n", add(a, b));
printf("Result: %d\n", subtract(a, b));
好吧,您可以定义一个重载方法,例如:
int add(const std::string & str )
{
std::stringstream ss(str);
int a, b,sum;
ss >> a; ss >> b;
return add(a, b);
}
据我了解你的问题,你想知道是否有办法减少
int a, b;
ss >> a >> b;
cout << (a + b) << endl;
类似于(注意这只是伪代码)
cout << ((ss >> ?) + (ss >> ?)) << endl;
无法避免声明临时变量。
首先,正如其他人指出的那样,如果操作顺序很重要,则需要它们。其次,你需要在运算符的 right-hand-side 上有一个名字。
您可以手动指定临时文件的名称,但您仍然需要指定它们的类型。 C++ 是一种静态类型语言。 operator>>
无法在右侧为您创建动态推导类型的变量。
出于好奇,我尝试将流中的几个变量的读取抽象为仅类型规范
#include <iostream>
#include <tuple>
template <size_t I=0, typename... T>
std::enable_if_t<I==sizeof...(T)>
collect_impl(std::istream& s, std::tuple<T...>& vars) { }
template <size_t I=0, typename... T>
std::enable_if_t<I!=sizeof...(T)>
collect_impl(std::istream& s, std::tuple<T...>& vars) {
s >> std::get<I>(vars);
collect_impl<I+1>(s,vars);
}
template <typename... T>
auto collect(std::istream& s) {
std::tuple<T...> vars;
collect_impl(s,vars);
return vars;
}
void awesome_function(std::tuple<int,int> ii) {
std::cout << std::get<0>(ii) << ' ' << std::get<1>(ii) << std::endl;
}
void less_awesome_function(int i2, int i1) {
std::cout << i1 << ' ' << i2 << std::endl;
}
int main() {
const auto ii = collect<int,int>(std::cin);
std::cout << std::get<0>(ii) << ' ' << std::get<1>(ii) << std::endl;
// we can also do
awesome_function(collect<int,int>(std::cin));
// with C++17 apply we can even do this
std::apply(less_awesome_function,collect<int,int>(std::cin));
}
给定以下代码:
#include <string>
#include <sstream>
int add(int a, int b) {
return a + b;
}
int main() {
std::string str = "1 2";
std::stringstream ss(str);
int a, b;
ss >> a;
ss >> b;
printf("Result: %d\n", add(a, b));
}
我想知道是否有任何方法可以减少此处部分的冗长:
int a, b;
ss >> a;
ss >> b;
printf("Result: %d\n", add(a, b));
并减少添加到类似内容中的调用:
add(ss >> ?, ss >> ?) // ? because I don't know what'd you'd put there.
基本上,把它变成一条线。
你的意思是这样的?
int sum( istream & is ) {
int n, total = 0;
while( is >> n ) {
total += n;
}
return total;
}
您可以创建一个函数
int getInt(std::istream& instr)
{
int n;
instr >> n;
return n;
}
然后使用
printf("Result: %d\n", add(getInt(ss), getInt(ss)));
PS
如果 add
的参数评估顺序很重要,则该方法将不起作用。例如,您不能使用:
printf("Result: %d\n", subtract(getInt(ss), getInt(ss)));
其中 subtract
具有通常的含义。
您当然可以使用:
int a = getInt(ss);
int b = getInt(ss);
printf("Result: %d\n", add(a, b));
printf("Result: %d\n", subtract(a, b));
好吧,您可以定义一个重载方法,例如:
int add(const std::string & str )
{
std::stringstream ss(str);
int a, b,sum;
ss >> a; ss >> b;
return add(a, b);
}
据我了解你的问题,你想知道是否有办法减少
int a, b;
ss >> a >> b;
cout << (a + b) << endl;
类似于(注意这只是伪代码)
cout << ((ss >> ?) + (ss >> ?)) << endl;
无法避免声明临时变量。 首先,正如其他人指出的那样,如果操作顺序很重要,则需要它们。其次,你需要在运算符的 right-hand-side 上有一个名字。
您可以手动指定临时文件的名称,但您仍然需要指定它们的类型。 C++ 是一种静态类型语言。 operator>>
无法在右侧为您创建动态推导类型的变量。
出于好奇,我尝试将流中的几个变量的读取抽象为仅类型规范
#include <iostream>
#include <tuple>
template <size_t I=0, typename... T>
std::enable_if_t<I==sizeof...(T)>
collect_impl(std::istream& s, std::tuple<T...>& vars) { }
template <size_t I=0, typename... T>
std::enable_if_t<I!=sizeof...(T)>
collect_impl(std::istream& s, std::tuple<T...>& vars) {
s >> std::get<I>(vars);
collect_impl<I+1>(s,vars);
}
template <typename... T>
auto collect(std::istream& s) {
std::tuple<T...> vars;
collect_impl(s,vars);
return vars;
}
void awesome_function(std::tuple<int,int> ii) {
std::cout << std::get<0>(ii) << ' ' << std::get<1>(ii) << std::endl;
}
void less_awesome_function(int i2, int i1) {
std::cout << i1 << ' ' << i2 << std::endl;
}
int main() {
const auto ii = collect<int,int>(std::cin);
std::cout << std::get<0>(ii) << ' ' << std::get<1>(ii) << std::endl;
// we can also do
awesome_function(collect<int,int>(std::cin));
// with C++17 apply we can even do this
std::apply(less_awesome_function,collect<int,int>(std::cin));
}