当前位置:网站首页>The mystery of any type conversion
The mystery of any type conversion
2022-07-18 02:28:00 【blackstar】
background
struct A{
A(int a){
this->a = a;
}
int a;
};
namespace Test{
struct A{
A(int a){
this->a = a;
}
int a;
};
}
void AnyCast(std::any& param){
const auto value = std::any_cast<Test::A>(param).a;
std::cerr << "value : " << value << std::endl;
}
int main(){
A a = 1;
auto param = std::make_any<A>(a);
AnyCast(param);
return 0;
}
Whether the above conversion is successful ?
doubt 1
Why do you customize the same type name with the same memory structure , Just because the namespace is different, it will lead to conversion exceptions ? Whether namespace removal is normal ? To make sure that the compilation passes , You need to separate custom types in different modules .
// module.h
#pragma once
#include <memory>
#include <any>
class ModuleImpl;
class Module{
public:
Module();
void AnyCast(std::any& param);
private:
std::shared_ptr<ModuleImpl> _impl;
};
// module.cpp
#include "module.h"
#include <iostream>
struct A {
A(int a) {
this->a = a;
}
int a;
};
class ModuleImpl {
public:
void AynyCast(std::any& param)
{
const auto value = std::any_cast<A>(param).a;
std::cerr << "value : " << value << "\n";
}
};
Module::Module()
: _impl(std::make_shared<ModuleImpl>())
{
}
void Module::AnyCast(std::any& param)
{
_impl->AynyCast(param);
}
Will there be any exceptions in the above conversion ?
doubt 2
Separate modules , Adding namespaces won't be a problem ? In response to this question , It's not impossible , To validate the :
There is a feeling of knowing each other from time to time .
uncover any_cast The veil of
Here we use MSVC Version implementation any_cast For example . First, let's look at its implementation logic :
template <class _Ty>
_NODISCARD remove_cv_t<_Ty> any_cast(any& _Any) {
static_assert(is_constructible_v<remove_cv_t<_Ty>, _Remove_cvref_t<_Ty>&>,
"any_cast<T>(any&) requires remove_cv_t<T> to be constructible from remove_cv_t<remove_reference_t<T>>&");
const auto _Ptr = _STD any_cast<_Remove_cvref_t<_Ty>>(&_Any);
if (!_Ptr) {
_Throw_bad_any_cast();
}
return static_cast<remove_cv_t<_Ty>>(*_Ptr);
}
The key function :any_cast<_Remove_cvref_t<_Ty>>(&_Any)
template <class _ValueType>
_NODISCARD _ValueType* any_cast(any* const _Any) noexcept {
// retrieve a pointer to the _ValueType contained in _Any, or null
static_assert(!is_void_v<_ValueType>, "std::any cannot contain void.");
if constexpr (is_function_v<_ValueType> || is_array_v<_ValueType>) {
return nullptr;
} else {
if (!_Any) {
return nullptr;
}
return _Any->_Cast<_Remove_cvref_t<_ValueType>>();
}
}
The key function :_Any->_Cast<_Remove_cvref_t<_ValueType>>()
template <class _Decayed>
_NODISCARD _Decayed* _Cast() noexcept { // if *this contains a value of type _Decayed, return a pointer to it
return const_cast<_Decayed*>(static_cast<const any*>(this)->_Cast<_Decayed>());
}
The key function :static_cast<const any>(this)->_Cast<_Decayed>()*
template <class _Decayed>
_NODISCARD const _Decayed* _Cast() const noexcept {
// if *this contains a value of type _Decayed, return a pointer to it
const type_info* const _Info = _TypeInfo();
if (!_Info || *_Info != typeid(_Decayed)) {
return nullptr;
}
if constexpr (_Any_is_trivial<_Decayed>) {
// get a pointer to the contained _Trivial value of type _Decayed
return reinterpret_cast<const _Decayed*>(&_Storage._TrivialData);
} else if constexpr (_Any_is_small<_Decayed>) {
// get a pointer to the contained _Small value of type _Decayed
return reinterpret_cast<const _Decayed*>(&_Storage._SmallStorage._Data);
} else {
// get a pointer to the contained _Big value of type _Decayed
return static_cast<const _Decayed*>(_Storage._BigStorage._Ptr);
}
}
The key code of this problem :
// if *this contains a value of type _Decayed, return a pointer to it
const type_info* const _Info = _TypeInfo();
if (!_Info || *_Info != typeid(_Decayed)) {
return nullptr;
}
You can use a line of code to explain :
typeid(A) == typeid(Test::A)
Set up ?
I don't say much nonsense , Let's go straight to work :
struct A {
A(int a) {
this->a = a;
}
int a;
};
namespace Test {
struct A {
A(int a) {
this->a = a;
}
int a;
};
}
int main()
{
const auto same = typeid(A) == typeid(Test::A);
std::cerr << "same : " << std::boolalpha << same << std::endl;
return 0;
}
summary
As a partner ( feel ) grid ( fish ) Software development engineer of , Finally, it's not too much to summarize .
In the use of any During type conversion , Make sure that the type source is unique Do not copy code casually between different modules Only code can solve BUG
This time any The mystery of type conversion End of the flower !!!
边栏推荐
- three.js无限跑动VR小游戏
- 2022 global developer salary PK: China ranks 19th, and using go language is the most profitable
- 云呐-动环监控系统实现无人化的快速故障处理
- 苹果和前设计总监 Jony lve 分道扬镳
- 年轻人抛弃新式美妆集合店
- 许式伟:Go+ 演进之路
- 2022-04-20 Unity入门7——物理系统之碰撞检测
- Involve yourself? After imagen, it launched an image model generated by 20billion text, which stunned netizens!
- Kotlin StateFlow 搜索功能的实践 DB + NetWork
- 2022-04-18 Unity入门1——窗口布局
猜你喜欢
随机推荐
手机怎样控制led显示屏发视频?
[benefit activity] stack a buff for your code! Click "tea" to receive the gift
Analysis of key technologies of Pan cloud desktop
H5打开微信小程序
Open source real-time data warehouse Apache Doris graduated, how to go further in the future?
如何复活古人?#MetaHuman 让万年前的骨架重获肉身
2022-04-18 Unity入门1——窗口布局
云呐-机房动环监控扩容方案
Experiment 1 Security mechanism of SQL Server
mysql show variables 查的是哪个表里面的数据?
全球No.1港口航运人工智能企业中集飞瞳,港航人工智能AI产品成熟化标准化大规模应用,先进核心技术为港口船公司大幅提效降本智能化
Google 推荐在 MVVM 架构中使用 Kotlin Flow
卷到自己?继 Imagen 之后,推出200 亿文本生成的图像模型惊呆网友!
Young people abandon new beauty collection stores
Redis使用管道PipeLine
Want to go whoring for nothing, right? Enough for you this time!
易基因|ENCODE组蛋白ChIP-seq和转录因子ChIP-seq数据标准及处理流程
可落地的DDD(7)-战术设计上的一些误区
Container interview questions
2022-04-20 Unity入门6——光源组件





![[hero planet July training leetcode problem solving daily] 15th binary tree](/img/01/89e2c60fade3148ca658551ac41b23.png)







