forward a struct with a unique_ptr
Aug 8, 2017 at 9:07pm UTC
I'm attempting to pass a rvalue struct, which has a unique_ptr as one of its members, as an argument to a member function, which then uses the rvalue in a std::pair definition.
Compile error however occurs, which is:
error: no matching function for call to ‘std::pair<int , db_info>::pair(int &, db_info)’
the header looks as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
#include <include/SQLAPI.h>
#include <map>
#include <memory>
struct db_info {
std::string product;
std::string con_str;
std::string usr;
std::string pswd;
std::string modify_begin;
std::string select_begin;
SAClient_t con_cl; // type of connection
std::unique_ptr<SAConnection> con;
};
class db_connector {
using info_map = std::map<int , db_info>;
public :
db_connector() { }
~db_connector() { }
using const_iterator = info_map::const_iterator;
const_iterator begin() const { return db_cons.begin(); }
const_iterator end() const { return db_cons.end(); }
void add_connection(int , db_info &&);
db_info * get_db_info(int db_id) { return &db_cons.at(db_id); }
bool connect (int );
bool disconnect (int );
private :
info_map db_cons;
};
the .cpp file looks like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
#include "db_connector.h"
//void db_connector::add_connection(int db_id, db_info dbi) {
void db_connector::add_connection(int db_id, db_info && dbi) {
db_cons.insert(std::make_pair(db_id, std::forward<db_info>(dbi) ));
// db_cons.insert(std::make_pair(db_id, dbi)); // this doesn't compile, because db_info has a unique_ptr as an attribute, which cannot be copied.
}
bool db_connector::connect (int db_id) {
db_info dbi {db_cons.at(db_id)};
try {
db_cons.at(db_id).con->Connect(dbi.con_str.c_str(), dbi.usr.c_str(), dbi.pswd.c_str(), dbi.con_cl);
}
catch (SAException &x) {
// thread safe log message required
// std::cout << (const char*)x.ErrText() << "\n";
return false ;
}
return true ;
}
bool db_connector::disconnect (int db_id) {
try {
db_cons.at(db_id).con->Disconnect();
}
catch (SAException &x) {
// thread safe log message required
// std::cout << (const char*)x.ErrText() << "\n";
return false ;
}
return true ;
}
The error occurs on this line "db_cons.insert(std::make_pair(db_id, std::forward<db_info>(dbi) ));"
I used a std::forward on an rvalue, since I thought that would get around the fact that a unique_ptr is part of the struct.
Can somebody explain why the error occurs and how to get around the error?
Aug 9, 2017 at 1:13am UTC
Use
std::forward only with
forwarding references
(to propagate the value category that an object had when the call was made).
To specify that an object may be moved from, use
std::move
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
#include <iostream>
#include <string>
#include <memory>
#include <map>
struct SAConnection { /* ... */ };
enum SAClient_t : int ;
struct db_info {
std::string product;
std::string con_str;
std::string usr;
std::string pswd;
std::string modify_begin;
std::string select_begin;
SAClient_t con_cl; // type of connection
std::unique_ptr<SAConnection> con;
};
using info_map = std::map<int , db_info>;
info_map db_cons ;
void add_connection( int db_id, db_info&& dbi ) {
// or better: void add_connection( int db_id, db_info dbi ) { // pass by value
db_cons.emplace ( db_id, std::move(dbi) ) ;
// note: this clumsier construct would also work
// db_cons.insert ( std::make_pair ( db_id, std::move(dbi) ) ) ;
}
int main() {
db_info dbi ;
dbi.con = std::make_unique<SAConnection>() ;
// ...
add_connection( 72, std::move(dbi) ) ;
}
http://coliru.stacked-crooked.com/a/2a302124f0e62934
Topic archived. No new replies allowed.