Передача std::string в шаблонную функцию класса

Рейтинг: -2Ответов: 1Опубликовано: 05.04.2023

Пишу обертку на C++ над Си-шной библиотекой sqlite. Вот есть у меня класс Statement. В нем реализованы методы setParam для int, double, blob, std::string и NULL:

 void setParam(int pos, const void * val, size_t size);
 void setParam(const std::string & name, const void * val, size_t size);
 void setParam(int pos, const double val);
 void setParam(const std::string & name, const double val);
 void setParam(int pos, const int val);
 void setParam(const std::string & name, const int val);
 void setParam(int pos, const std::string & val);
 void setParam(const std::string & name, const std::string & val);

Как можно видеть, привязка параметра есть как по индексу, так и по имени параметра. Но я также хочу реализовать возможность привязки к запросу объекта любого класса, с предоставлением функции преобразования этого объекта к int, double, string или blob. Как по индексу параметра:

 template<typename From, typename To>
 void setParam(int pos, const From & val, Converter<From, To> converter)
 {
   setParam(pos, converter(val));
 }

 Statement stmt(db, "SELECT * FROM artists WHERE ArtistId = ?;");
 stmt.setParam(1, bpt::second_clock::universal_time(), bpt::to_iso_extended_string);

Здесь Converter это просто

template<typename From, typename To>
using Converter = std::function<To(From)>;

И это прекрасно работает. НО!! Если я сделаю такой же шаблон, но для привязки параметра по имени:

template<typename From, typename To>
void setParam(std::string name, const From & val, Converter<From, To> converter)
{
  setParam<From, To>(bindParameterIndex(name), val, converter);
}

то при компиляции следующего кода:

Statement stmt(db, "SELECT * FROM artists WHERE ArtistId = :val;");
stmt.setParam("val", bpt::second_clock::universal_time(), bpt::to_iso_extended_string);

Получаю ошибку:

    error: no matching function for call to 'sqlitelib::Statement::setParam(const char [4],     boost::posix_time::ptime, std::__cxx11::string (&)(boost::posix_time::ptime))'
   stmt.setParam("val", bpt::second_clock::universal_time(), bpt::to_iso_extended_string);

Я не силен в шаблонах, и не понимаю, почему здесь std::string низводится до const char[4], а также не знаю как это предотвратить. Просьба, помочь в решении проблемы. Заранее благодарен

Я пробовал передавать строку по значению, а не по ссылке. Результата нет

Ответы

▲ 0
"val" == {'v', 'a', 'l', \0};

В классе std::string есть метод c_str(), который возвращает указатель на первый символ строки, представленный как массив символов типа char. Если вы передадите name.c_str() в функцию, она будет ожидать аргумент типа const char*, который будет указывать на начало строки "val" в памяти.

Если вы получаете const char[4] вместо объекта std::string, то возможно, что в функции, которая принимает аргумент const string &name, name было передано как C-строка, используя метод c_str().

есть еще name.data() - возвращает non-const массив.