簡體   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?

考慮一下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";
   }
}

現在,我的問題是這樣的:我可以在get_number()的函數定義的第一行中刪除int ,並在我的代碼頂部用所有可能要返回的類型聲明它,例如進行如下聲明: :

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

並以某種方式讓它根據要存儲函數返回值的變量執行不同的返回值? 目前,我只是在將名稱更改為get_someType同時編寫基本相同功能的多個定義。

我希望我可以用這種語法做類似聲明的事情:

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

我的願望是做類似的事情:

int x;
x = get_number(int);

我確信這將無法正常工作! 因為用沒有名字的參數來定義函數的源代碼是不可能的...

首先,您發現的get_number實現寫得不好:輸入時出現EOF,您會怎么想? 它會盡可能快地打印“請輸入有效的數字\\ n”,直到您終止程序為止。

其次,您不能在返回類型上重載-這意味着您不能擁有僅在返回類型上有所不同的函數。

最后,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";
}

然后可以使用if (get(my_int)) ...if (get(my_double))等。

由於不能保證輸入會成功,因此您真的應該提供布爾返回類型(如圖所示),或者在輸入明確無法成功后拋出異常。

您正在尋找功能template s

此代碼有錯誤(請不要使用cplusplus.com作為參考),因為它不會檢查是否接收到來自std::cin輸入。

模板化的示例如下所示(未經測試):

#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;
    }
}

要將我在下面的評論合並到此答案中,請執行以下操作:在類模板或函數模板中,可以使用typename代替class來聲明模板化類型。 我更喜歡typename因為我們要處理POD類型而不是class es。

可以使用模板來完成。

在這里,您可以找到一些適合初學者的模板教程(從58開始。) http://thenewboston.org/list.php?cat=16

您可以使用模板,但據我所知,您的函數也必須具有該模板類型的參數,例如:

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";
   }
}

模板( 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM