gpt4 book ai didi

c++ - 同时使用参数重载和返回类型重载

转载 作者:行者123 更新时间:2023-11-28 03:00:41 24 4
gpt4 key购买 nike

我试图制作一个程序,自动检测用户输入的数据类型。我的方法:

int input(istream& i)
{
int k;
i>>k;
return k;
}
float input(istream& i)
{
float k;
i>>k;
return k;
}
void showval(int h){cout<<h;}
void showval(float h){cout<<h;}
int main()
{
showval(input(cin));
return 0;
}

如您所见,我同时使用了两个不同函数的参数重载返回类型重载。然而,该程序给出错误为

"new declaration float input(istream& i) disambiguates the old declaration int input(istream& i)”.

我不明白,这怎么会产生歧义。是不是因为这两个不同的函数(showvalinput)是依赖的?

此外,在阅读了几篇关于重载的文章之后,我意识到在 C++ 中,方法只有在参数不同时才可以重载。然而this link 他有一个技巧,可以通过返回类型重载函数。是否可以在我的程序中使用相同的技巧?此外,有什么方法可以告诉编译器函数 input 具有依赖于用户的参数,并且其数据类型可能不同也可能不同。 C++ 是否禁止这种可能性?

最佳答案

假设类型如 intfloat特定的,链接问题中显示的代理对象等类型是通用的。我们的选择一开始是特定的,在这种情况下,我们只是顺风顺水,或者我们产生一个通用类型并处理所有不同的我们可能支持的特定类型。

链接问题中显示的代理对象是 variant type 的示例, 和 boost::variant 是这个的通用实现。例如,boost::variant<int, float>允许我们持有 intfloat .

我的推荐真的取决于你想要什么。你

  1. 想要指定您希望从用户那里获得的类型并抛出意外输入? (特定的开始和海岸)或者,
  2. 想要根据用户输入的内容产生不同的类型并指定一组您可以处理的类型? (产生一个通用类型并处理各种特定类型)

指定您期望从用户那里得到的类型

在这种情况下,我们可以简单地使函数模板化,并通过模板参数指定我们期望的类型。

显示的示例完全通用,但您可以使用各种技术限制模板参数。查看my answer关于这个话题。

#include <iostream>

/* Read data of type T from an input stream. */
template <typename T>
T read(std::istream &strm) {
T val;
strm >> val;
if (!strm) {
throw /* something */;
} // if
return val;
}

/* Print data of type T. */
template <typename T>
void print(const T &val) {
std::cout << val;
}

int main() {
print(read<int>(std::cin));
}

这将产生一个 int输入如 1甚至对于 1. 这样的输入, 1.01.2 .

处理您可能从用户那里获得的不同类型

在这种情况下,我们实际上是在对来自用户的输入流进行词法分析。我们的read函数将产生一个通用类型,boost::variant<int, float> .

#include <iostream>

#include <boost/variant.hpp>

/* Naive implementation of a lexer. */
boost::variant<int, float> read(std::istream &strm) {
std::string lexeme;
strm >> lexeme;
try {
std::size_t idx;
auto val = std::stoi(lexeme, &idx);
if (idx == lexeme.size()) { // Make sure we converted the entire lexeme.
return val;
} // if
} catch (const std::exception &) {
// Do nothing. We'll try to lex it as float instead.
} // try
std::size_t idx;
auto val = std::stof(lexeme, &idx);
if (idx == lexeme.size()) { // Make sure we converted the entire lexeme.
return val;
} // if
throw /* something */;
}

/* Print the type and the value, to check that we have the correct type. */
void print(const boost::variant<int, float> &val) {
class visitor : public boost::static_visitor<void> {
public:
void operator()(int that) const {
std::cout << "int: " << that << std::endl;
}
void operator()(float that) const {
std::cout << "float: " << that << std::endl;
}
}; // visitor
boost::apply_visitor(visitor(), val);
}

int main() {
print(read(std::cin));
}

这种方法会产生 int输入如 1 , 并产生 float输入如 1. , 1.0作为1.2 .

如您所见,我们产生了一个通用类型,boost::variant<int, float> ,并处理各种特定类型,intfloat , 在访客中。

关于c++ - 同时使用参数重载和返回类型重载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20933292/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com