变量函数返回类型C ++

时间:2015-02-28 04:58:45

标签: c++ c++14

因此,在C ++ 14中使用新的auto返回类型推导,有没有办法创建具有不同返回类型的函数?

例如:

auto replaceStr(string base, string search, string replace) {
  size_t found = base.find(search);
  if (found == string::npos) {
    return false; //Return this is replace is not found
  }
  else {
    base.replace(found, (found+search.length()), replace);
    return base; //Return this after the replacement
  }
}

我知道,这不起作用。那么有没有办法让它发挥作用?

编辑:评论中的大多数人都告诉我这是不可能的,因为编译器在编译时不知道函数的返回类型。那么也许我们可以让函数有一个带有可选返回类型的默认返回类型?

7 个答案:

答案 0 :(得分:4)

C ++是一种静态类型语言:无法返回编译时未知的变量类型。

请参阅this SO question有关静态和动态类型的语言差异,也称为weak or strong typing

关于C ++ 14 auto返回类型,请参阅When should I use C++14 automatic return type deduction?

答案 1 :(得分:1)

  

评论中的大多数人都告诉我这是不可能的   编译器不知道函数的返回类型   汇编

编译器确实知道类型。如果编译器无法推断出类型,则程序格式错误并且不会编译。 auto并不代表弱类型,它代表一个占位符类型,可以使用模板参数推导推断出来。

答案 2 :(得分:1)

正如已经指出的,编译器需要在编译时知道函数返回类型。

对于您的特定示例,您可以返回std::pair<bool, string>。在没有进行替换的情况下,该对的second成员将被忽略。

auto res = replaceStr(base, search, replace);
if (res.first) {
    auto newBase = res.second;
    // ...
}

答案 3 :(得分:1)

虽然这不能直接回答您的问题,但执行此操作的常用方法是传递参考:

bool replaceStr(string &base, string search, string replace) {
    size_t found = base.find(search);
    if (found == string::npos) {
        return false; //Return this is replace is not found
    }
    base.replace(found, (found+search.length()), replace);
    return true;
}

然后你会像:

一样使用它
if (replaceStr(base,search,replace)) {
    // it was replaced, use the modified base.
}
else {
    // it wasn't replaced
}

答案 4 :(得分:0)

C ++并不直接支持变量返回类型,但它当然可以实现。这是一个变量返回类型的示例,其中在一种情况下在编译时选择了返回类型,在另一种情况下在运行时选择了返回类型。

#include <string>
#include <memory>
#include <sstream>
#include <iostream>

// dynamically varying return type
class AnyBase
{
public:
    virtual ~AnyBase() {};
    const std::string as_string() const
    {
        return this->as_string_v();
    }


private:
    virtual const std::string as_string_v() const = 0;
};
typedef AnyBase Any;

template<typename T>
class AnyDerived : public AnyBase
{
    T* obj_ptr_;

public:
    template<typename... Args>
    AnyDerived(Args&&... args)
    {
        obj_ptr_ = new T(std::forward<Args...>(args...));
    }

    ~AnyDerived()
    {
        delete obj_ptr_;
    }

private:
    const std::string as_string_v() const;
    const char* type_string_v() const;
};

template<class T>
const std::string AnyDerived<T>::as_string_v() const
{
    std::ostringstream oss;
    oss << *obj_ptr_;
    return oss.str();
}

std::ostream& operator<<(std::ostream& os, const Any& a)
{
    os << a.as_string();
    return os;
}


std::unique_ptr<Any> foo(bool as_char)
{
    if (as_char)
        return std::unique_ptr<Any>{new AnyDerived<char>('1')};
    else
        return std::unique_ptr<Any>{new AnyDerived<int>(1)};
}


// statically varying return type
template<typename T>
T bar()
{
    return 1;
}

template<>
char bar<char>()
{
    return '1';
}


int main()
{
    bool as_char;
    as_char = true;
    const auto a1 = foo(as_char);
    as_char = false;
    const auto a2 = foo(as_char);
    const auto a3 = bar<int>();
    const auto a4 = bar<char>();

    std::cout << "*a1: " << *a1 << std::endl;
    std::cout << "*a2: " << *a2 << std::endl;
    std::cout << " a3: " <<  a3 << std::endl;
    std::cout << " a4: " <<  a4 << std::endl;
}

a1包含指向char的指针,a2包含指向int的指针,a3inta4char。正如您在main()中所看到的那样,它可以变得相当透明。

输出:

*a1: 1
*a2: 1
 a3: 1
 a4: 1

答案 5 :(得分:0)

在这种情况下,我只会犯错误。

string replaceStr(string base, string search, string replace) {
  size_t found = base.find(search);
  if (found == string::npos) {
    throw MyException(); 
  }
  else {
    base.replace(found, (found+search.length()), replace);
    return base; //Return this after the replacement
  }
}

但是如果你想创建一个类似工厂的函数,它可以返回任何东西:

  • 使用多态并返回指向基础的指针
  • 将您想要的任何内容投射到std::shared_ptr<void>
  • 使用boost :: any

答案 6 :(得分:0)

您的函数可以返回void*,它可以指向任何内容。但是,如果您不小心,这种方法可能会让您在管理内存方面遇到麻烦。