模板元编程如何专注于集合

Posted

技术标签:

【中文标题】模板元编程如何专注于集合【英文标题】:template meta-programming how to specialize on a collection 【发布时间】:2016-02-07 20:47:14 【问题描述】:

我创建了以下UtlSharedIPCWrapper 模板类,可以访问放置在进程间内存中的用户定义类型。

通常此类与简单类型一起使用,例如:

// construct a FaultReport - default to no faults
auto faultWrapper = managed_shm.construct<
    UtlSharedIPCWrapper<uint64_t>>("FaultReport")(0);

这很好用,但是我最近需要使用 boost 共享内存映射集合 (boost::interprocess::map) 作为模板参数),如下所示:

using char_allocator = boost::interprocess::managed_shared_memory::allocator<char>::type;
using shm_string = boost::interprocess::basic_string<char, std::char_traits<char>, char_allocator>;
using KeyType = shm_string;
using ValueType = std::pair<const KeyType, shm_string>;
using ShmemAllocator = boost::interprocess::allocator<ValueType, boost::interprocess::managed_shared_memory::segment_manager>;
using SharedMemoryMap = boost::interprocess::map<shm_string, shm_string, std::less<KeyType>, ShmemAllocator>;

...

// create a new shared memory segment 2K size
managed_shared_memory managed_shm(open_only, "sharedmemname");

//Initialize the shared memory STL-compatible allocator
ShmemAllocator alloc(managed_shm.get_segment_manager());

auto pSharedNVPairs = managed_shm.find<UtlSharedIPCWrapper<
    SharedMemoryMap>>("NameValuePairs").first;

我的问题是如何更改下面的模板类定义以将 collection::value 类型作为参数传递,而不是通过 pSharedNVPairs-&gt;getSharedData() 更新临时映射并将其再次写回共享内存作为一个操作单独读取整个映射通过pSharedNVPairs-&gt;setSharedData(*pSharedNVPairs)。我知道这对于不是集合的类型会有所不同,因此必须执行一些模板元编程魔术来选择性启用 if 等,但是我希望在我的类中添加一个方法,类似于

// I don't know the correct signature here
void setSharedDataValue(const T::value_type& rSharedDataValue) 
    boost::interprocess::scoped_lock<upgradable_mutex_type> lock(mMutex);
    ... not sure what to do here to update the collection


template<typename T>
struct UtlSharedIPCWrapper 
private:
    using upgradable_mutex_type = boost::interprocess::interprocess_upgradable_mutex;

    mutable upgradable_mutex_type mMutex;
    /*volatile*/ T mSharedData;
public:
    // explicit constructor used to initialize directly from existing memory
    explicit UtlSharedIPCWrapper(const T& rInitialValue)
        : mSharedData(rInitialValue)
    

    T getSharedData() const 
        boost::interprocess::sharable_lock<upgradable_mutex_type> lock(mMutex);
        return mSharedData;
    

    void setSharedData(const T& rSharedData) 
        boost::interprocess::scoped_lock<upgradable_mutex_type> lock(mMutex);
        // update the shared data copy mapped - scoped locked used if exception thrown
        // a bit like the lock guard we normally use
        this->mSharedData = rSharedData;
    
;

【问题讨论】:

我怀疑你真的想问一个 - 非常 - 不同的问题 - 在这种情况下,请通过将代码示例扩展为自包含来澄清 @sehe 我同意这个问题可能有点含糊,但是我确实有两种不同的情况,我想在上面处理,一种是简单的整数类型,另一种是收藏。我想知道如何使用模板魔法使适当的模板专业化工作 @Sehe using GCC 4.9.1 我收到以下错误。这让我觉得我真的需要一些 std::enable_if 机制来有效地注释掉整个方法,如果模板的实例化不是完整的或更具体的类型容器 - 你怎么看? - 我不知道该怎么做。这是一个简短的编译器错误。在包含在“struct UtlSharedIPCWrapper”的实例化中的文件中:ALBFDaemon.cpp:347:31:此处需要 UtlSharedIPCWrapper.h:49:10:错误:'long long unsigned int' 不是类、结构或联合类型 【参考方案1】:

为什么不直接

// I don't know the correct signature here
void setSharedDataValue(const typename T::value_type& rSharedDataValue)      
    boost::interprocess::scoped_lock<upgradable_mutex_type> lock(mMutex);
    mSharedData.insert(rSharedDataValue);

【讨论】:

我在 Visual Studio 2015 中尝试了上述方法,但我得到:C2825: 'T': must be a class or namespace when after '::'.不确定语法是。当然,提供 T::value_type 的意图正是我想要提供的,因为在这种情况下我需要将 std::pair 元素插入到 std::map 中,我不确定这段代码会发生什么我有 UtlSharedIPCWrapper 的情况 - 这种方法会消失 - 这是我不清楚的整个元编程。 MSVC 有一些与模板中的名称查找相关的非标准行为。您能否提供一个重现您的问题的 /selfcontained/ 示例?

以上是关于模板元编程如何专注于集合的主要内容,如果未能解决你的问题,请参考以下文章

Item 48:了解模板元编程

C++模板元编程深度解析:探索编译时计算的神奇之旅

什么样的C++模板编程可以称为“元编程”? [关闭]

C++ 和 D 中的元编程

C++ 模板元编程的最佳介绍? [关闭]

Item 48:了解模板元编程