Почему g ++ говорящий 'соответствие для ‘оператора =’, когда ясно существует, и Visual Studio видит, что существует?

Я пишу интерфейсную библиотеку, которая предоставляет доступ к переменным в таблицах (до теоретически бесконечной глубины) в объекте типа 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++. Кто-либо может пролить какой-либо свет на это или рекомендовать какие-либо решения?

6
задан pdusen 22 December 2009 в 17:49
поделиться

1 ответ

В разделе 5.17 стандарта ИСО

сказано

Существует несколько операторов присваивания, все из которых группируются справа налево. Все они требуют модифицируемого значения 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);
6
ответ дан 17 December 2019 в 02:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: