【问题标题】:A function with variable return type具有可变返回类型的函数
【发布时间】:2018-03-08 00:33:55
【问题描述】:

我希望能够创建一个函数GetInput(),它将一个类作为参数,并返回输入的任何内容。函数定义如下所示:

GetInput(class type) {
    if (type == string) {
        string stringInput;
        cin >> stringInput;
        return stringInput;
    }
    else if (type == int) {
        int intInput;
        cin >> intInput;
        return intInput;
    }
    else {
        return NULL;
    }
}

我不知道要为函数的返回类型写什么,因为它可以是字符串或整数。我怎样才能使这个功能起作用?

【问题讨论】:

  • 你知道模板吗?您是否有不想为此使用模板的原因?
  • @EricPostpischil 我没学过模板
  • 如果您通过将type 作为模板参数传递它来使type 成为实际类型而不是变量,则可以这样做。另请查看if constexpr

标签: c++ function return-type


【解决方案1】:

你不能让它成为一个实际的参数,但你可以通过创建一个函数模板(也称为模板函数)来做类似的事情:

template<class T>
T GetInput() {
    T input;
    cin >> input;
    return input;
}

你可以这样使用它:

string stringInput = getInput<string>();
int intInput = getInput<int>();

getInput&lt;string&gt;getInput&lt;int&gt; 被认为是不同的函数,由编译器生成 - 因此它被称为模板。

注意 - 如果您使用多个文件,整个模板定义必须放在头文件而不是源文件中,因为编译器需要查看整个模板才能从中生成函数。

【讨论】:

  • 你可以在源文件中定义模板就好了,在标题中声明它们是有问题的。
  • @nwp 我们在谈论 C++ 模板,对吗?在头文件中实现 then 是唯一的可移植方式
  • @GuillaumeRacicot 不,不是。 template &lt;class T&gt; void f(){} int main() { f&lt;int&gt;(); } 是一个完全正确且可移植的 C++ 程序,在源文件中有一个模板。
  • @nwp 啊,我明白了。请注意,immibis 说“如果您使用多个文件......”
  • 注意问题显示函数返回NULL,如果类型不是stringint,则什么也不做。这可以通过返回NULL 的通用模板和读取并返回项目的stringint 的特化来完成。除了NULL 对于大多数类来说不是一个合适的值,所以必须为返回值计算其他东西。
【解决方案2】:

正如你所描述的,你无法让它工作。

但是,由于调用者需要知道正在读取什么类型,所以简单的解决方案是使用模板函数。

#include <iostream>

//   it is inadvisable to employ "using namespace std" here 

template<class T> T GetInput()
{
    T Input;
    std::cin >> Input;
    return Input;
}

并使用

//   preceding code that defines GetInput() visible to compiler here

int main()
{
     int xin = GetInput<int>();
     std::string sin = GetInput<std::string>();
}

模板化函数适用于输入流(如std::cin)支持流式传输且可以按值返回的任何类型T。您可以使用各种技术(特征、部分特化)来强制执行约束(例如,如果函数用于函数逻辑不起作用的类型,则会产生有意义的编译错误)或为不同类型提供不同的功能。

当然,既然你所做的只是阅读std::cin,你实际上可以直接阅读

#include <iostream>

int main()
{
    int xin;
    std::string sin;

    std::cin >> xin;
    std::cin >> sin;
}

【讨论】:

    猜你喜欢
    • 2015-03-06
    • 2023-04-10
    • 2018-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多