可变函数返回类型C++
Varying function return type C++
那么,使用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
}
}
我知道这行不通。那么,有办法让它发挥作用吗?
EDIT:评论中的大多数人都告诉我这是不可能的,因为编译器在编译时不知道函数的返回类型。那么,也许我们可以让函数有一个默认的返回类型和可选的返回类型?
C++是一种静态类型语言:在编译时无法返回未知的变量类型。
请参阅这个SO关于静态和动态类型语言差异的问题,这些差异也被称为弱类型或强类型。
关于C++14 auto
返回类型,请参阅何时应使用C++14自动返回类型扣除?
正如已经指出的,编译器需要在编译时知道函数返回类型。
对于您的特定示例,您可以返回一个std::pair<bool, string>
。在没有进行替换的情况下,该对的second
成员被忽略。
auto res = replaceStr(base, search, replace);
if (res.first) {
auto newBase = res.second;
// ...
}
虽然这不能直接回答您的问题,但一种常见的方法是传递引用:
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
}
从那以后,评论中的大多数人都告诉我这是不可能的编译器不知道函数的返回类型汇编
编译器确实知道类型。如果编译器无法推导类型,则表示程序格式不正确,不会进行编译。auto
并不意味着弱类型,它表示一种占位符类型,可以使用模板参数推导来推导。
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
在这种情况下,我只会抛出一个错误。
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
函数可以返回void*
,它可以指向任何东西。然而,如果你不小心,这种方法可能会让你在管理内存方面遇到麻烦。
- 如何获取std::result_of函数的返回类型
- 奇怪的结构&GCC&clang(void*返回类型)
- 如何建立使用模板函数的lambda函数的尾部返回类型
- 为什么与常规GCC不同,即使有"学究性错误",MinGW-GCC也能容忍丢失的返回类型
- 在没有定义返回类型的函数中返回布尔值,并将结果保存在无错误的char编译中-为什么
- 特征::矩阵<双精度,1,3> 结构类型函数中的返回类型函数
- 函数作为模板参数,是否对返回类型强制约束
- C++中函数的向量返回类型引发错误
- 检查函数返回类型是否与STL容器类型值相同
- 为什么返回类型中需要typename?C++
- <Windows>为什么 std::thread::native_handle 返回类型为"long long unsigned int"的值,而不是 void*(又名 HANDLE)?
- 警告:在函数返回类型 [-Wignore 限定符] 时忽略类型限定符
- 为什么 c++(g++) 不允许模板返回类型和函数名称之间有空格?
- 为什么返回类型的'const'限定符对标有 __forceinline/内联的函数没有影响?
- 推导 std::vector::back() 的返回类型
- 在 c++ 中将函数返回类型指定为模板参数
- 使用 SWIG 更改生成的 CS 函数中的返回类型
- QtQuick - qml:28:错误:未知方法返回类型:自定义类型
- 基于返回类型的转换和过载扣除
- 当返回类型声明为 ListNode 时,我们是否可以返回 false<T>*