Компилятор превращает строку & в basic_string <> & - PullRequest
1 голос
/ 22 апреля 2010

Я возвращаюсь к C ++ после долгих лет, потраченных на другие технологии, и застрял в странном поведении при вызове некоторых методов, принимающих std :: string в качестве параметров:

Пример звонка: LocalNodeConfiguration *LocalNodeConfiguration::ReadFromFile(std::string & path) { // ... throw configuration_file_error(string("Configuration file empty"), path); // ... }

Когда я компилирую, я получаю это (я обрезал имена файлов для удобства чтения):

/usr/bin/g++    -g -I/home/shtong/Dev/OmegaNoc/build -I/usr/share/include/boost-1.41.0   -o CMakeFiles/OmegaNocInternals.dir/configuration/localNodeConfiguration.cxx.o -c /home/shtong/Dev/OmegaNoc/source/configuration/localNodeConfiguration.cxx
    .../localNodeConfiguration.cxx: In static member function ‘static OmegaNoc::LocalNodeConfiguration* OmegaNoc::LocalNodeConfiguration::ReadFromFile(std::string&)’:
    .../localNodeConfiguration.cxx:72: error: no matching function for call to ‘OmegaNoc::configuration_file_error::configuration_file_error(std::string, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&)’
    .../configurationManager.hxx:25: note: candidates are: OmegaNoc::configuration_file_error::configuration_file_error(std::string&, std::string&)
    .../configurationManager.hxx:22: note:                 OmegaNoc::configuration_file_error::configuration_file_error(const OmegaNoc::configuration_file_error&)

Итак, насколько я понимаю, компилятор считает, что мой параметр path в какой-то момент превратился в basic_string, поэтому не нашел перегрузки конструктора, которую я хочу использовать. Но я не совсем понимаю, почему произошла эта трансформация.

Некоторые поиски в сети предложили мне использовать g ++, но я уже использовал его. Так что любой другой совет будет оценен:)

Спасибо

Ответы [ 3 ]

12 голосов
/ 22 апреля 2010

Проблема не в basic_string, потому что basic_string<char, restOfMess> эквивалентно string.

Проблема в том, что функция обеспечивает только

f(string&, string&) {
//------^

но вы звоните как

 f(string("blah"), path);
// ^^^^^^^^^^^^^^

Это rvalue (временный объект), и rvalue не может быть привязано к изменяемой ссылке. Вам нужно либо изменить прототип так, чтобы он принимал константные ссылки, либо просто передавать по значению:

    f(const string&, string&) {
//----^^^^^^
or
    f(string, string&) {

Или предоставить изменяемую ссылку (если вам действительно нужно изменить первый аргумент в этой функции):

string s = "blah blah blah";
f(s, path);
2 голосов
/ 22 апреля 2010

Проблема здесь в том, что первый (хорошо, хорошо, оба, но первый вызывает проблему) параметр в конструкторе configuration_file_error является ссылкой не const, и вы не можете связать временный объект (например, тот, который вы пытаетесь передать) на не-const ссылку.

Конструктор, вероятно, должен принимать const ссылок, если ему не нужно изменять строки. Поскольку вы выбрасываете это как исключение, я надеюсь, что на самом деле не нужно изменять его параметры, потому что объекты, на которые они ссылаются, вероятно, будут уничтожены при размотке стека!

0 голосов
/ 23 апреля 2010

string это просто псевдоним для basic_string<>. Из стандарта (§21.2), который, несомненно, копируется непосредственно в ваши заголовочные файлы,

typedef basic_string<char> string;

, где basic_string<char> получает два аргумента по умолчанию из

template<class charT, class traits = char_traits<charT>,
class Allocator = allocator<charT> > class basic_string;

Эти аргументы несколько загадочны и никогда не изменятся, если вы не переопределите их вручную.

(basic_string<wchar_t> - это отдельный тип, с которым вы можете столкнуться при Юникоде.)

...