为什么 std:map 不能接受指针作为键值?

Why std:map can't accept a pointer as key-value?

本文关键字:键值 指针 不能接受 std map 为什么      更新时间:2023-10-16

我正在尝试实现将MUTEX对象放在映射中的JNI函数。编译时,我会遇到错误" ...因为JNI通过指针",并且我在参数中转换。

为什么std:map不能接受指针作为键值?

给出错误的指令是这样的:

std::pair<_jobject , boost::fibers::recursive_mutex> v = 
   std::pair<_jobject , boost::fibers::recursive_mutex>(*ref, *new boost::fibers::recursive_mutex());
#include <jni.h>
#include <map>
#include "ext_concurrent_fiber_FiberLock.h"
#include <boost/fiber/recursive_mutex.hpp>
std::map<_jobject, boost::fibers::recursive_mutex> mutexes;
boost::fibers::recursive_mutex lock;
// ‘std::pair<_jobject*, boost::fibers::recursive_mutex>::
//pair(_jobject&, boost::fibers::recursive_mutex&)’
// mutexes.insert(std::pair<jobject , boost::fibers::recursive_mutex>((_jobject&)ref, *new boost::fibers::recursive_mutex()));
JNIEXPORT jboolean JNICALL Java_ext_concurrent_fiber_FiberLock_setLockIfNotPresent
  (JNIEnv * env, jclass clazz, jobject ref){
  lock.lock();
  std::map<_jobject, boost::fibers::recursive_mutex>::iterator i =mutexes.find(*ref);
    if(i == mutexes.end())
    {
        std::pair<_jobject , boost::fibers::recursive_mutex> v
        =std::pair<_jobject , boost::fibers::recursive_mutex>(*ref, *new boost::fibers::recursive_mutex());
        mutexes.insert(v);
        lock.unlock();
        return true;
    }
   lock.unlock();
   return false;
  }

下面您可以看到日志:

 jni:
         [echo] Generating JNI headers
         [exec] mkdir -p target/c++
         [exec] g++ -c -Wall -fPIC -I/usr/lib/jvm/java-8-oracle/include/ -I/usr/lib/jvm/java-8-oracle/include/linux -I/usr/include/boost_1_66_0  -o target/c++/ext_concurrent_fiber_NativeFiber.o src/main/c++/ext_concurrent_fiber_NativeFiber.cpp
         [exec] mkdir -p target/c++
         [exec] g++ -c -Wall -fPIC -I/usr/lib/jvm/java-8-oracle/include/ -I/usr/lib/jvm/java-8-oracle/include/linux -I/usr/include/boost_1_66_0  -o target/c++/ext_concurrent_fiber_FiberLock.o src/main/c++/ext_concurrent_fiber_FiberLock.cpp
         [exec] src/main/c++/ext_concurrent_fiber_FiberLock.cpp: In function ‘jboolean Java_ext_concurrent_fiber_FiberLock_setLockIfNotPresent(JNIEnv*, jclass, jobject)’:
         [exec] src/main/c++/ext_concurrent_fiber_FiberLock.cpp:21:105: error: no matching function for call to ‘std::pair<_jobject, boost::fibers::recursive_mutex>::pair(_jobject&, boost::fibers::recursive_mutex&)’
         [exec]         =std::pair<_jobject , boost::fibers::recursive_mutex>(*ref, *new boost::fibers::recursive_mutex());
         [exec]                                                                                                          ^
         [exec] In file included from /usr/include/c++/6/bits/stl_algobase.h:64:0,
         [exec]                  from /usr/include/c++/6/bits/stl_tree.h:63,
         [exec]                  from /usr/include/c++/6/map:60,
         [exec]                  from src/main/c++/ext_concurrent_fiber_FiberLock.cpp:3:
         [exec] /usr/include/c++/6/bits/stl_pair.h:423:9: note: candidate: template<class ... _Args1, long unsigned int ..._Indexes1, class ... _Args2, long unsigned int ..._Indexes2> std::pair<_T1, _T2>::pair(std::tuple<_Args1 ...>&, std::tuple<_Args2 ...>&, std::_Index_tuple<_Indexes1 ...>, std::_Index_tuple<_Indexes2 ...>)
         [exec]          pair(tuple<_Args1...>&, tuple<_Args2...>&,
         [exec]          ^~~~
         [exec] /usr/include/c++/6/bits/stl_pair.h:423:9: note:   template argument deduction/substitution failed:
         [exec] src/main/c++/ext_concurrent_fiber_FiberLock.cpp:21:105: note:   ‘_jobject’ is not derived from ‘std::tuple<_Args1 ...>’
         [exec]         =std::pair<_jobject , boost::fibers::recursive_mutex>(*ref, *new boost::fibers::recursive_mutex());
         [exec]                                                                                                          ^
         [exec] In file included from /usr/include/c++/6/bits/stl_algobase.h:64:0,
         [exec]                  from /usr/include/c++/6/bits/stl_tree.h:63,
         [exec]                  from /usr/include/c++/6/map:60,
         [exec]                  from src/main/c++/ext_concurrent_fiber_FiberLock.cpp:3:
         [exec] /usr/include/c++/6/bits/stl_pair.h:356:9: note: candidate: template<class ... _Args1, class ... _Args2> std::pair<_T1, _T2>::pair(std::piecewise_construct_t, std::tuple<_Args1 ...>, std::tuple<_Args2 ...>)
         [exec]          pair(piecewise_construct_t, tuple<_Args1...>, tuple<_Args2...>);
         [exec]          ^~~~
         [exec] /usr/include/c++/6/bits/stl_pair.h:356:9: note:   template argument deduction/substitution failed:
         [exec] src/main/c++/ext_concurrent_fiber_FiberLock.cpp:21:105: note:   ‘boost::fibers::recursive_mutex’ is not derived from ‘std::tuple<_Args1 ...>’
         [exec]         =std::pair<_jobject , boost::fibers::recursive_mutex>(*ref, *new boost::fibers::recursive_mutex());
         [exec]                                                                                                          ^

您的问题与指针无关。问题是您要在地图中存储的对象类型是不可复制的,因此您无法构造它们,然后将它们复制到地图中。相反,您可以告诉地图将它们直接构造到位:

std::map<jobject, boost::fibers::recursive_mutex> mutexes;
boost::fibers::recursive_mutex lock;
JNIEXPORT jboolean JNICALL
Java_ext_concurrent_fiber_FiberLock_setLockIfNotPresent(JNIEnv* env, jclass clazz, jobject ref)
{
    std::lock_guard<boost::fibers::recursive_mutex> lck(lock);
    auto i = mutexes.find(ref);
    if(i == mutexes.end())
    {
        mutexes.emplace(std::piecewise_construct,
                        std::forward_as_tuple(ref),
                        std::tuple<>{});
        return true;
    }
    return false;
}

在这里,我已经将std::map::emplacestd::pairstd::piecewise_construct构造函数一起使用,告诉地图以构造其元素的位置。这样,不需要将静音复制到地图中。