因此,在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
}
}
我知道,这不起作用。那么有没有办法让它发挥作用?
编辑:评论中的大多数人都告诉我这是不可能的,因为编译器在编译时不知道函数的返回类型。那么也许我们可以让函数有一个带有可选返回类型的默认返回类型?
答案 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
的指针,a3
是int
和a4
是char
。正如您在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>
。 答案 6 :(得分:0)
您的函数可以返回void*
,它可以指向任何内容。但是,如果您不小心,这种方法可能会让您在管理内存方面遇到麻烦。