Я пишу интерфейсную библиотеку, которая предоставляет доступ к переменным в таблицах (до теоретически бесконечной глубины) в объекте типа regula::State
. Я выполняю это путем перегрузки operator[]
в классе, который затем возвращает другой из того же самого класса и вызовы operator[]
снова по мере необходимости. Например:
regula::State t;
t["math"]["pi"] = 3.14159;
Вышеупомянутое, как предполагается, помещает значение 3.14159
в переменной pi
в таблице math
. В основном это делает это имеет t
возвратите объектное представление прокси math
, который возвращает другое объектное представление прокси pi
, к которому мы на самом деле сохраняем переменную. Внутренности этого не действительно относятся к вопросу, но вот функциональный заголовок.
LObject LObject::operator[] (const std::string name);
В основном, в примере выше, программа должна звонить t
operator[]
со строкой "math"
и возвратите другой объект и затем назовите тот объект operator[]
со строкой "pi"
, который возвращает конечный объект и затем присваивает значение тому использованию operator=
.
template <typename T>
T LObject::operator= (const T& value);
T
возвращенный просто копия value
переданный.
Теперь, мой код не производит ошибок в Visual C++ 2008 и работы отлично. Но когда я пытаюсь скомпилировать его на Linux с g++
, Я получаю следующую ошибку:
../../test/regula-test.cpp:100: error: no match for ‘operator=’ in
‘L.regula::State::operator[](std::basic_string<char, std::char_traits<char>,
std::allocator<char> >(((const char*)"Numbers"), ((const std::allocator<char>&)((const
std::allocator<char>*)(& std::allocator<char>()))))) = Numbers’
../../include/regula.hpp:855: note: candidates are: regula::LObject&
regula::LObject::operator=(const regula::LObject&)
По некоторым причинам, g++
кажется, пытается звонить operator=
на operator[]
, вместо на возвращенном объекте как он, как предполагается.
Я могу на самом деле зафиксировать эту ошибку путем замены типа возврата на operator=
с void
:
template <typename T>
/*T*/ void LObject::operator= (const T& value);
Но это не предпочтительно, и кроме того, у меня есть подобные ошибки в нескольких других местоположениях со столь же перегруженный operator==
:
../../test/regula-test.cpp:153: error: no match for ‘operator==’ in ‘pi ==
L.regula::State::operator[](std::basic_string<char, std::char_traits<char>,
std::allocator<char> >(((const char*)"pi"), ((const std::allocator<char>&)((const
std::allocator<char>*)(& std::allocator<char>())))))’
Я не понимаю, почему эта ошибка происходит в g ++, или почему это не происходит в Visual C++. Кто-либо может пролить какой-либо свет на это или рекомендовать какие-либо решения?
сказано
Существует несколько операторов присваивания, все из которых группируются справа налево. Все они требуют модифицируемого значения l в качестве их левого операнда , а типом выражения присваивания является тип его левого операнда . Результатом операции присваивания является значение, сохраненное в левом операнде после выполнения присваивания; результатом является значение l.
Ваш оператор operator=
возвращает не только неправильный тип, но и даже не значение lvalue. Если предположить, что сообщение об ошибке GCC не включало никаких других кандидатов, кроме оператора operator=(const regula::LObject&)
, то GCC просто проигнорировал вашу перегрузку полностью. Оператор operator=
, на который он ссылается, является автоматически генерируемой функцией по умолчанию.
На второй взгляд, ваш оператор оператор[]
также должен возвращать ссылку. Как написано, никакие выражения присваивания, подобные Вашему примеру, не должны работать вообще.
Итак, у Вас должны быть функции
LObject &LObject::operator[] (const std::string name);
и
template <typename T>
LObject &LObject::operator= (const T& value);