有没有一种方法可以根据函数参数值动态更改C ++中函数的返回类型?

时间:2020-10-13 06:29:55

标签: c++ c++11 c++14 c++17

我正在解决一个问题,该问题要求我根据提供的函数参数值返回不同的返回类型。

我想做这样的事情-

在下面的代码中,doSomething()是一个已经存在的函数(已被许多客户端使用),它以mode作为函数参数,并已经返回std::list<ReturnType>

基于模式值,我必须创建另一个子功能,该子功能返回shared_future<std::list<ReturnType>>

如何更改此代码,使其可以根据模式值返回两种返回类型之一?

请注意:ReturnType是我们在整个课程中使用的template typename

代码:

    std::shared_future<std::list<ReturnType> > futureValue() {
        return functionReturningSharedFuture();
    }
    
    std::list<ReturnType> listValue() {
        return functionReturningList();
    }
    std::list<ReturnType> doSomething(int mode) {
        if(mode == 1){
            // new functionality that I added
            return futureValue(); // This (obviously) errors out as of now
        }
        else{
            // already there previously
            return listValue();
        }
    }
    
    int main() {
        doSomething(1);
        return 0;
    }

如何更改此代码,使其可以根据模式值返回两种返回类型之一?

约束和问题:

  1. 如果我们提供一个额外的函数参数(例如true值),可以通过函数重载轻松解决此问题,但是该多余的参数没有用,因为我们已经在使用mode 。另外,添加几乎没有用的变量也不是一个好的设计。
  2. 主要限制因素之一是,有些已经在使用doSomething()的客户端期望使用std::list<ReturnType>,因此我无法返回boost::anystd::variant或类似的内容。
  3. 我尝试使用std::enable_if,但由于我们在运行时获取了模式值,因此无法解决问题。
  4. 我们不能使用模板元编程,因为那会改变在客户端调用函数的方式。我们付不起钱。

谢谢。

2 个答案:

答案 0 :(得分:2)

无法完成。

您只能使用一个具有给定签名的功能。如果您已经有调用代码,期望它返回一个std::list<ReturnType>,就是这样。完成了。

如果您可以保证所有现有调用代码都像这样

auto l = obj.doSomething(1);

然后,您可以将返回类型更改为在任何调用代码中看起来像std::list的东西。但是如果有任何调用代码,看起来像

std::list<ReturnType> l = obj.doSomething(1);

然后不在桌子上。

您可能需要在这里重新考虑您的设计。

答案 1 :(得分:1)

在示例main中,我看到了doSomething(1);,所以也许在调用站点,在编译时总是知道参数mode的值。在这种情况下,一种选择是使doSomething成为template<int mode>函数。我正在考虑这样的事情:

#include <iostream>
#include <list>
#include <vector>

// assuming you cannot change this (actually you have changed it in you example, ...)
std::list<int> doSomething(int mode) {
    std::cout << "already existing function\n";
    return std::list<int>{1,2,3};
}

// then you can put this too
template<int N>
auto doSomething();

template<>
auto doSomething<10>() {
    std::cout << "new function\n";
    return std::vector<int>{1,2,3};
}

int main() {
    auto x = doSomething(3);
    auto y = doSomething<10>();
}

可能的另一种选择是在if中使用auto的{​​{3}}整数和decltype(auto)中的doSomething / ./bin/kafka-console-producer.sh --broker-list localhost:9093 --topic oauth2-demo-topic --producer.config ./config/sasl-oauth2-producerapp-config.properties 返回类型,但是我没有尝试过了。