Skip to content

Instantly share code, notes, and snippets.

@linuxlizard
Created September 25, 2023 13:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save linuxlizard/f9cfb7940af694993a791b52dcc63138 to your computer and use it in GitHub Desktop.
Save linuxlizard/f9cfb7940af694993a791b52dcc63138 to your computer and use it in GitHub Desktop.
storing a unique_ptr<> in a std::map
// gcc -g -Wall bssmap.cc -lstdc++ -std=c++20 -o bssmap
#include <cstring>
#include <iostream>
#include <memory>
#include <map>
#include <string>
//
// simple demo shim of the C struct BSS
extern "C" {
#define MAX_BSS_STR 32
struct BSS {
char bssid_str[MAX_BSS_STR + 1];
};
struct BSS *bss_new(const char *bssid_str) {
struct BSS *bss = (struct BSS*)calloc(1, sizeof(struct BSS));
strncpy(bss->bssid_str, bssid_str, MAX_BSS_STR);
printf("%s bss=%p\n", __func__, bss);
return bss;
}
void bss_free(struct BSS **p_bss) {
free(*p_bss);
*p_bss = nullptr;
}
} // end extern "C"
//
// end of shim
// forward declaration for unique_ptr<> Deleter
void release_bss(struct BSS *);
// https://en.cppreference.com/w/cpp/memory/unique_ptr
using unique_bss_t = std::unique_ptr<struct BSS, decltype(&release_bss)>;
// key: the bssid as printable string
// value: safe container holding the C data structure
std::map<std::string, unique_bss_t> bss_db;
void release_bss(struct BSS *ptr )
{
std::cout << __func__ << " ptr=" << reinterpret_cast<void *>(ptr) << "\n";
bss_free(&ptr);
// ptr == nullptr at this point
}
// how to store into the map so that a new BSS will release the previous
int main()
{
// actual BSS comes from decoding a complex linux netlink(7) nl80211 data
// structure
struct BSS *bss;
bss = bss_new("004068112233");
std::string s { bss->bssid_str };
unique_bss_t ubss { bss, &release_bss };
// bss_db[ s ] = std::move(ubss);
// bss_db[ s ] = ubss;
// bss_db[ s ] = { bss, &release_bss };
// auto p = std::make_pair(s,ubss);
// TODO add more bss*
//bss = bss_new("004068aabbcc");
//bss = bss_new("004068112233"); // replace existing
}
@linuxlizard
Copy link
Author

Using GCC from the cli, I get an enormous template error.

CLion (clang-tidy) is giving me a simple error around the variations I've been trying lines 63-65.
In template: no matching constructor for initialization of 'std::unique_ptr<BSS, void (*)(BSS *)>'

@linuxlizard
Copy link
Author

Solution from someone on a discord channel: https://godbo.lt/z/fz8z4YqWP

"you cannot use bss_db[ s ] = { bss, &release_bss }; because the unique_bss_t is not default constructible. for that map has emplace: bss_db.emplace(s, std::move(ubss)); "

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment