我正在编写一个接口库,允许在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[]
的{{1}}并返回另一个对象,然后调用该对象的"math"
字符串operator[]
,它返回最终对象,然后使用"pi"
将值赋给该值。
operator=
返回的template <typename T>
T LObject::operator= (const T& value);
只是T
传递的副本。
现在,我的代码在Visual C ++ 2008中产生NO错误并且运行正常。但是当我尝试使用value
在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==
我不明白为什么在g ++中发生这个错误,或者为什么它在Visual C ++中没有发生。任何人都可以对此有所了解或推荐任何解决方案吗?
答案 0 :(得分:6)
ISO标准的第5.17节说
有几个赋值运算符,所有赋值运算符都从右到左分组。所有都需要一个可修改的左值作为左操作数,和赋值表达式的类型是其左操作数的类型。赋值操作的结果是赋值发生后存储在左操作数中的值; 结果是左值。
您的operator=
不仅会返回错误的类型,甚至也不会返回左值。假设GCC的错误消息不包括operator=(const regula::LObject&)
以外的任何其他候选者,GCC完全忽略了您的过载。它提到的operator=
是默认的,自动生成的函数。
乍一看,您的operator[]
也应该返回参考。如上所述,没有像你的例子那样的赋值表达式应该可以工作。
所以,你应该有功能
LObject &LObject::operator[] (const std::string name);
和
template <typename T>
LObject &LObject::operator= (const T& value);