简体   繁体   English

在C ++中,调用我的函数以根据程序的需要返回不同的类型时,是否可以做一些时髦的事情?

[英]Is it possible, in C++, to do some funky stuff when calling my function to return different types depending on my program's needs?

Consider the useful code by Zaita posted at cplusplus.com , in particular the part which gets numbers safely, modified to be a function in my case: 考虑一下Zaita发布在cplusplus.com上的有用代码,特别是安全获取数字的部分,在我的情况下修改为函数:

int get_number()
{
   /**
    * cplusplus.com/forum/articles/6046
    * gets number from input stream
    **/

   string input = "";
   int number = 0;

   while (true)
   {
      getline(cin, input);
      stringstream checks(input);
      if (checks >> number)
         return number;
      cout << "Please enter a valid number\n";
   }
}

Now, my question is this: Can I remove the int on the first line of the function definition for get_number(), and declare it at the top of my code with all the types I might want to return such as doing some declarations like this: 现在,我的问题是这样的:我可以在get_number()的函数定义的第一行中删除int ,并在我的代码顶部用所有可能要返回的类型声明它,例如进行如下声明: :

double get_number();
int get_number();
long get_number();
unsigned short get_number();
...
...

And somehow get it to do different returns depending on the variable I want to store the return from the function with? 并以某种方式让它根据要存储函数返回值的变量执行不同的返回值? Currently I simply writing multiple definitions of essentially the same function while changing the name to get_someType 目前,我只是在将名称更改为get_someType同时编写基本相同功能的多个定义。

I am hoping I can do something like declare with this sort of syntax: 我希望我可以用这种语法做类似声明的事情:

int get_number(int);
double get_double(double);
...
...

And my desire would be to do something like: 我的愿望是做类似的事情:

int x;
x = get_number(int);

I am sure this will NOT work however! 我确信这将无法正常工作! Because it would be impossible to define the function's source code with parameters with no names... 因为用没有名字的参数来定义函数的源代码是不可能的...

Firstly, the get_number implementation you've found is badly written: what do you think happens when you get an EOF on input? 首先,您发现的get_number实现写得不好:输入时出现EOF,您会怎么想? It spins around printing "Please enter a valid number\\n" as fast as it can until you kill the program.... 它会尽可能快地打印“请输入有效的数字\\ n”,直到您终止程序为止。

Secondly, you can't overload on return type - which means you can't have functions that only differ in the return type. 其次,您不能在返回类型上重载-这意味着您不能拥有仅在返回类型上有所不同的函数。

Finally, C++ has templates that can do what I think you want... 最后,C ++的模板可以完成我认为您想要的...

template <typename T>
bool get(T& x)
{
    std::string input;
    if (!getline(std::cin, input))
        return false;
    stringstream checks(input);
    if (checks >> x)
        return true;
    cout << "Please enter a valid value\n";
}

You can then use if (get(my_int)) ... or if (get(my_double)) etc.. 然后可以使用if (get(my_int)) ...if (get(my_double))等。

As input can not be guaranteed to succeed, you really should either provide a boolean return type (as illustrated) or throw an exception once it's clear input can not succeed. 由于不能保证输入会成功,因此您真的应该提供布尔返回类型(如图所示),或者在输入明确无法成功后抛出异常。

You're looking for function template s ! 您正在寻找功能template s

This code is buggy (please don't use cplusplus.com as a reference), since it doesn't check that input from std::cin is received. 此代码有错误(请不要使用cplusplus.com作为参考),因为它不会检查是否接收到来自std::cin输入。

A templated example would look something like this (untested): 模板化的示例如下所示(未经测试):

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

template <typename T>
T get_number()
{
    std::string input = "";
    T number; // Don't initialise to zero
    bool done = false;

    while (!done)
    {
        if (std::getline(std::cin, input)) // check for success
        {
            std::istringstream checks(input);
            if (checks >> number)
            {
                done = true;
            }
            else
            {
                std::cout << "Please enter a valid number\n";
            }
        }
        else
        {
            throw std::runtime_error("No input was received\n");
        }
    }
    return number;
}

int main()
{
    try
    {
        int i = get_number<int>();
        float f = get_number<float>();
        double d = get_number<double>();
        char b = get_number<char>();
    }
    catch (const std::runtime_error& e)
    {
        std::cerr << e.what() << std::endl;
    }
}

To incorporate my comment below into this answer... In a class template or function template, typename can be used as an alternative to class to declare templated types. 要将我在下面的评论合并到此答案中,请执行以下操作:在类模板或函数模板中,可以使用typename代替class来声明模板化类型。 I prefer typename because we're dealing with POD-types and not class es. 我更喜欢typename因为我们要处理POD类型而不是class es。

This can be done with templates. 可以使用模板来完成。

Here you can find out some template tutorials for beginners (start from 58..) http://thenewboston.org/list.php?cat=16 在这里,您可以找到一些适合初学者的模板教程(从58开始。) http://thenewboston.org/list.php?cat=16

You can use templates, but as far as I know your function must have an argument of the type of that template as well, as in: 您可以使用模板,但据我所知,您的函数也必须具有该模板类型的参数,例如:

template <class T>
T get_number(T arg)
{
   /**
    * cplusplus.com/forum/articles/6046
    * gets number from input stream
    **/

   string input = "";
   T number = 0;

   while (true)
   {
      getline(cin, input);
      stringstream checks(input);
      if (checks >> number)
         return number;
      cout << "Please enter a valid number\n";
   }
}

The type of template ( T ) is resolved in compile time based on the type of argument passed to the function. 模板( T )的类型在编译时根据传递给函数的参数的类型进行解析。

template<class T>
T get_number()
{
   /**
    * cplusplus.com/forum/articles/6046
    * gets number from input stream
    **/

   string input = "";
   T genericobj;

   while (true)
   {
      getline(cin, input);
      stringstream checks(input);
      if (checks >> genericobj)
         return genericobj;
      cout << "Please enter a valid input\n" ;
   }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何使我的 function 根据使用 C++ 中的模板调用的类型返回不同的结果 - How do I make my function return different results depending on type it's been called using templates in C++ 在C ++中调用函数时我的程序崩溃 - My program crashes when calling a function in c++ 在C ++中,如何根据类中的参数返回不同的泛型类型? - In C++, how to return different generic types depending on argument in a class? 为什么用.Call 而不是.C 调用我的C++ function 时会出现段错误? - Why do I get a segfault when calling my C++ function with .Call rather than .C? C ++:为什么我的函数返回的参考地址与解除引用的指针的地址不同? - C++: Why does my function return a reference address different from the dereferenced pointer's address? 调用delete []会破坏我的C ++程序 - Calling delete[] breaks my C++ program 具有不同返回类型的C ++函数 - C++ function with different return types 如何确定我的程序需要运行哪些c ++可再发行组件? - How do I determine which c++ redistributables my program needs to run? C++ 模板以避免长开关,同时调用具有不同返回类型的 function - C++ templates to avoid long switches, while calling a function with different return types 我的 C++ 程序在它应该停止的时候并没有停止 - My C++ program doesn't stop when it's supposed to
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM