在C++中模拟 C# 的属性功能



我正试图使用std::shared_mutex为C++中的读写器锁编写一个接口,我希望它能自动识别哪些函数需要使用std::unique_lock(编写器(,哪些函数需要用到std::shared_lock。在过去编写了很多C#之后,我曾想过尝试模仿它的属性功能,但在谷歌上搜索后,我找不到任何关于这方面的信息。因此,我的问题是:在C++中,是否有可能基于函数的属性来专门化模板函数(使用类似std::enable_if的东西(?如果是这样的话,怎么能做到呢?

一些伪代码可以更好地解释我的意思:

private:
std::shared_ptr<_Ty> m_obj;
std::shared_mutex m_mtx;
public:
using pointer = decltype(m_obj)::pointer;
// Note: This locking would of course have to apply outside these operator-functions's lifetimes...
// Here std::has_attribute is a placeholder for what I'm looking for.
template std::enable_if<std::has_attribute<readerfunc>, pointer>::type operator->() const {
std::shared_lock<std::shared_mutex> lock(m_mtx);
return m_obj.get();
}
template std::enable_if<std::has_attribute<writerfunc>, pointer>::type operator->() const {
std::unique_lock<std::shared_mutex> lock(m_mtx);
return m_obj.get(); // The real implementation would perform a certain function here.
}

然后,如果所拥有的对象是读取器,则它将使用属性[[readerfunc]]声明其函数,如果它是写入器,则类似地,[[writerfunc]]声明它的函数,并且接口类将识别要使用哪个运算符重载。

您可以通过特性的模板专门化来获得一些属性。在现代C++中,常量值模板使其更加干净。

唯一需要注意的是,您的";属性";不能整齐地坐在功能旁边:

enum class rw_mode_t {
reader,
writer,
none,
};
// Declare the "attribute" with a default value.
template<auto T>
constexpr rw_mode_t rw_mode = rw_mode_t::none;
class X {
public:
void foo() {}
void bar() {}
};
// Set the "attribute" to something else than the default via specialization
template<>
constexpr rw_mode_t rw_mode<&X::foo> = rw_mode_t::reader;
template<>
constexpr rw_mode_t rw_mode<&X::bar> = rw_mode_t::writer;

然后你可以做一些类似的事情:

template<typename T>
class myWrapper{
std::shared_ptr<_Ty> m_obj;
std::shared_mutex m_mtx;
public:
void foo() {
constexpr rw_mode_t mode = rw_mode<&T::foo>;
if constexpr(mode == rw_mode_t::writer)) {
std::unique_lock<std::shared_mutex> lock(m_mtx);
m_obj->foo();
} 
else if constexpr(mode == rw_mode_t::reader) {
std::shared_lock<std::shared_mutex> lock(m_mtx);
m_obj->foo();
}
else {
m_obj->foo();
}
}
};

最新更新