文章目录
- mutable
- 其他
- Reference
mutable
- 当你定义一个类,并且在将类的实例当作参数传递过程中,需要用
const Class* cls_ptr
方式传递时,会存在一种情况,就是虽然cls_ptr为const,但是你还需要调用该类的方法,修改类中一些属性,来满足自己的需求;这个时候就需要将一些需要修改不受类的const修饰词影响的属性定义为mutable属性。
class Context {void set_stream(Stream stream) { stream_ = stream; }// 当Context的实例被const修饰时,只能调用`void Function const{}`的方法。否则会报错误。const Stream& stream() const { return stream_; }mutable Stream stream_;
}
源码参考:https://github.com/google/mediapipe/blob/3e9f86e580ad89519d8e7a228d247ca330d71409/mediapipe/framework/formats/tensor.h#L391
struct MtlResources;
class Tensor {class View {public:// Non-copyable.View(const View&) = delete;View& operator=(const View&) = delete;protected:explicit View(std::unique_ptr<absl::MutexLock>&& lock): lock_(std::move(lock)) {}std::unique_ptr<absl::MutexLock> lock_;};public:// No resources are allocated here.enum class ElementType {kNone,kFloat16,kFloat32,kUInt8,kInt8,kInt32,kChar,kBool};struct Shape {Shape() = default;Shape(std::initializer_list<int> dimensions) : dims(dimensions) {}Shape(const std::vector<int>& dimensions) : dims(dimensions) {}Shape(std::initializer_list<int> dimensions, bool is_dynamic): dims(dimensions), is_dynamic(is_dynamic) {}Shape(const std::vector<int>& dimensions, bool is_dynamic): dims(dimensions), is_dynamic(is_dynamic) {}int num_elements() const {return std::accumulate(dims.begin(), dims.end(), 1,std::multiplies<int>());}std::vector<int> dims;// The Tensor has dynamic rather than static shape so the TFLite interpreter// needs to be reallocated. Only relevant for CPU.bool is_dynamic = false;};// Quantization parameters corresponding to the zero_point and scale value// made available by TfLite quantized (uint8/int8) tensors.struct QuantizationParameters {QuantizationParameters() = default;QuantizationParameters(float scale, int zero_point): scale(scale), zero_point(zero_point) {}float scale = 1.0f;int zero_point = 0;};...private:friend class MtlBufferView;void Move(Tensor*);void Invalidate();ElementType element_type_;Shape shape_;QuantizationParameters quantization_parameters_;// The flags describe the current source of truth resource type.enum {kValidNone = 0,kValidCpu = 1 << 0,kValidMetalBuffer = 1 << 1,kValidOpenGlBuffer = 1 << 2,kValidOpenGlTexture2d = 1 << 3,kValidAHardwareBuffer = 1 << 5,};// A list of resource which are currently allocated and synchronized between// each-other: valid_ = kValidCpu | kValidMetalBuffer;mutable int valid_ = 0;// The mutex is locked by Get*View and is kept by all Views.mutable absl::Mutex view_mutex_;mutable void* cpu_buffer_ = nullptr;void AllocateCpuBuffer() const;// Forward declaration of the MtlResources provides compile-time verification// of ODR if this header includes any actual code that uses MtlResources.mutable std::unique_ptr<MtlResources> mtl_resources_;#ifdef MEDIAPIPE_TENSOR_USE_AHWBmutable std::shared_ptr<HardwareBuffer> ahwb_;// Allocates and pools HardwareBuffer instances. Holding the shared_ptr to the// pool ensures it outlives the internal ahwb_.std::shared_ptr<HardwareBufferPool> hardware_buffer_pool_;// Signals when GPU finished writing into SSBO so AHWB can be used then. Or// signals when writing into AHWB has been finished so GPU can read from SSBO.// Sync and FD are bound together.mutable EGLSyncKHR fence_sync_ = EGL_NO_SYNC_KHR;// This FD signals when the writing into the SSBO has been finished.mutable int ssbo_written_ = -1;// An externally set FD that is wrapped with the EGL sync then to synchronize// AHWB -> OpenGL SSBO.mutable int fence_fd_ = -1;// Reading from SSBO has been finished so SSBO can be released.mutable GLsync ssbo_read_ = 0;// An externally set function that signals when it is safe to release AHWB.// If the input parameter is 'true' then wait for the writing to be finished.mutable FinishingFunc ahwb_written_;mutable std::function<void()> release_callback_;bool AllocateAHardwareBuffer(int size_alignment = 0) const;void CreateEglSyncAndFd() const;
#endif // MEDIAPIPE_TENSOR_USE_AHWB// Use Ahwb for other views: OpenGL / CPU buffer.mutable bool use_ahwb_ = false;mutable uint64_t ahwb_tracking_key_ = 0;// TODO: Tracks all unique tensors. Can grow to a large number. LRU// (Least Recently Used) can be more predicted.// The value contains the size alignment parameter.static inline absl::flat_hash_map<uint64_t, int> ahwb_usage_track_;// Expects the target SSBO to be already bound.bool AllocateAhwbMapToSsbo() const;bool InsertAhwbToSsboFence() const;void MoveAhwbStuff(Tensor* src);void ReleaseAhwbStuff();void* MapAhwbToCpuRead() const;void* MapAhwbToCpuWrite() const;void MoveCpuOrSsboToAhwb() const;// Set current tracking key, set "use ahwb" if the key is already marked.void TrackAhwbUsage(uint64_t key) const;#if MEDIAPIPE_OPENGL_ES_VERSION >= MEDIAPIPE_OPENGL_ES_30mutable std::shared_ptr<mediapipe::GlContext> gl_context_;mutable GLuint opengl_texture2d_ = GL_INVALID_INDEX;mutable GLuint frame_buffer_ = GL_INVALID_INDEX;mutable int texture_width_;mutable int texture_height_;
#ifdef __EMSCRIPTEN__mutable bool texture_is_half_float_ = false;
#endif // __EMSCRIPTEN__void AllocateOpenGlTexture2d() const;
#if MEDIAPIPE_OPENGL_ES_VERSION >= MEDIAPIPE_OPENGL_ES_31mutable GLuint opengl_buffer_ = GL_INVALID_INDEX;void AllocateOpenGlBuffer() const;
#endif // MEDIAPIPE_OPENGL_ES_VERSION >= MEDIAPIPE_OPENGL_ES_31bool NeedsHalfFloatRenderTarget() const;
#endif // MEDIAPIPE_OPENGL_ES_VERSION >= MEDIAPIPE_OPENGL_ES_30
};
其他
上层用非const,底层传递过程中用const修饰的 一个思考就是:在不同调用层级中会使用不同的方法对同样的属性操作,比如在上层,context是非const的,所以可以调用一些set方法,设置一些属性;当传递到下层时,我们希望他们只使用这些设置好的属性,那么我们就将context的实例修饰成const,这样他只能调用这些
void Function const{}
方法。
- mutable 的使用思考, 是不是能够用于管理类的方法,控制哪些可以被const实例使用,哪些可以被非const实例使用,这样管理起来可以控制一些类的使用权限情况–方法层级的使用权限。