C++ any/optional/variant

std::any(C++17)

有点像python等脚本语言的动态类型,可以用于对C语言里void*类型的替换使用,相比void*类型安全,对于异常转换,可以通过try/catch进行捕获处理。

示例:

#include <any>
#include <iostream>
 
int main()
{
    std::cout << std::boolalpha;
 
    // any type
    std::any a = 1;
    std::cout << a.type().name() << ": " << std::any_cast<int>(a) << '\n';
    a = 3.14;
    std::cout << a.type().name() << ": " << std::any_cast<double>(a) << '\n';
    a = true;
    std::cout << a.type().name() << ": " << std::any_cast<bool>(a) << '\n';
 
    // bad cast
    try
    {
        a = 1;
        std::cout << std::any_cast<float>(a) << '\n';
    }
    catch (const std::bad_any_cast& e)
    {
        std::cout << e.what() << '\n';
    }
 
    // has value
    a = 2;
    if (a.has_value())
    {
        std::cout << a.type().name() << ": " << std::any_cast<int>(a) << '\n';
    }
 
    // reset
    a.reset();
    if (!a.has_value())
    {
        std::cout << "no value\n";
    }
 
    // pointer to contained data
    a = 3;
    int* i = std::any_cast<int>(&a);
    std::cout << *i << "\n";
}

/* output
int: 1
double: 3.14
bool: true
bad any_cast
int: 2
no value
3
*/

参考资料:std::any - cppreference.com

https://devblogs.microsoft.com/cppblog/stdany-how-when-and-why

std::optional(C++17)

对函数返回结果做一层封装,常见用于给返回值增加是否出错标记;比如pair<string,bool>这种返回值,对于返回的string希望可以判断是否函数内部异常出错,如果返回空,是正常逻辑空,还是异常错误空,有时候调用方是需要做分类处理的。示例代码:

#include <iostream>
#include <optional>
using namespace std;
string getString1(int param)
{
    if (0 == param) return "";
    string str; // do logic
    return str;
}
optional<string> getString2(int param)
{
    if (0 == param) return {};
    string str; // do logic
    return str;
}
int main()
{
    int param = 0;
    string str1 = getString1(param);
    if (str1.empty()) { cout << "get empty str" << endl; }
    
    optional<string> opt_str2 = getString2(param);
    if (!opt_str2) { cout << "get failed, error happen" << endl; }
    return 0;
}

参考资料:https://zhuanlan.zhihu.com/p/64985296

std::variant(C++17)

C++11如果想要一个函数返回多个变量,可以返回std::pair或std::tuple,C++17提供了std::variant;可以理解为类型安全的union(union多个字段共用内存,这里不共用),可以通过该特性对上述optional的返回错误做明确赋值。

示例代码:

#include <iostream>
#include <optional>
#include <variant>
using namespace std;
string getString1(int param)
{
    if (0 == param)
        return "";
    string str; // do logic
    return str;
}
optional<string> getString2(int param)
{
    if (0 == param)
        return {};
    string str; // do logic
    return str;
}
variant<string,int> getString3(int param)
{
    if (0 == param) return -1;
    string str; // do logic
    return str;
}
int main()
{
    int param = 0;
    string str1 = getString1(param);
    if (str1.empty()) { cout << "get empty str" << endl; }
    
    optional<string> opt_str2 = getString2(param);
    if (!opt_str2) { cout << "get failed, error happen" << endl; }

    variant<string, int> var_str3 = getString3(param);
    if (auto p = get_if<string>(&var_str3))
        cout << "get normal str:" << *p << endl;
    if (auto p = get_if<int>(&var_str3))
        cout << "get failed error happen:" << *p << endl;

    return 0;
}
/*
get empty str
get failed, error happen
get failed, error happen:-1
*/

protobuf::any(proto3)

在pb结构定义中,可以使用any类型,表示任意类型,使用时可以通过强制转化达到动态类型效果。

syntax = "proto3";
import "google/protobuf/any.proto";

message AnyType {
  google.protobuf.Any data = 1;
}

代码示例:todo

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值