C++ 为什么 g++ 说 'no match for 'operator=' 显然有,而 Visual Studio 可以看到有?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1947971/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why is g++ saying 'no match for ‘operator=’ when there clearly is, and Visual Studio can see that there is?
提问by pdusen
I'm writing an interface library that allows access to variables within tables (up to a theoretically infinite depth) in an object of type regula::State
. I'm accomplishing this by overloading operator[]
within a class, which then returns another of that same class, and calls operator[]
again as needed. For example:
我正在编写一个接口库,它允许访问类型为 的对象中的表中的变量(理论上可达无限深度)regula::State
。我通过operator[]
在一个类中重载来实现这一点,然后返回同一个类的另一个,并operator[]
根据需要再次调用。例如:
regula::State t;
t["math"]["pi"] = 3.14159;
The above is supposed to place the value 3.14159
within variable pi
in table math
. Basically, it does this by have t
return a proxy object representing math
, which returns another proxy object representing pi
, to which we actually save the variable. The internals of this aren't really relevant to the question, but here is the function header.
上面应该将值放在 table 中的3.14159
变量pi
中math
。基本上,它通过t
返回一个代表 的代理对象来实现math
,该代理对象返回另一个代表 的代理对象pi
,我们实际上将变量保存到该代理对象。这个内部结构与问题并不真正相关,但这里是函数头。
LObject LObject::operator[] (const std::string name);
Basically, in the example above, the program should call t
's operator[]
with the string "math"
and return another object, and then call that object's operator[]
with the string "pi"
, which returns the final object, and then assigns the value to that one using operator=
.
基本上,在上面的示例中,程序应该使用字符串调用t
's并返回另一个对象,然后使用字符串调用该对象,返回最终对象,然后使用.operator[]
"math"
operator[]
"pi"
operator=
template <typename T>
T LObject::operator= (const T& value);
The T
returned is just a copy of the value
passed.
在T
返回的只是一个副本value
通过。
Now, my code produces NO errors in Visual C++ 2008 and works perfectly. But when I try to compile it on Linux with g++
, I get the following error:
现在,我的代码在 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&)
For some reason, g++
seems to be trying to call operator=
on operator[]
, rather than on the returned object like it is supposed to be.
出于某种原因,g++
似乎是试图调用operator=
上operator[]
像它应该是,而不是返回的对象。
I can actually fix this error by replacing the return type on operator=
with void
:
实际上,我可以通过更换返回类型修复这个错误operator=
有void
:
template <typename T>
/*T*/ void LObject::operator= (const T& value);
But this is not preferable, and besides, I have similar errors in several other locations with a similarly overloaded operator==
:
但这不是可取的,此外,我在其他几个类似重载的位置也有类似的错误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>())))))'
I don't understand why this error is occurring in g++, or why it is not occurring in Visual C++. Can anyone shed any light on this or recommend any solutions?
我不明白为什么这个错误会出现在 g++ 中,或者为什么它没有出现在 Visual C++ 中。任何人都可以对此有所了解或推荐任何解决方案吗?
采纳答案by Potatoswatter
Section 5.17 of the ISO standard says
ISO 标准的第 5.17 节说
There are several assignment operators, all of which group right-to-left. All require a modifiable lvalue as their left operand, and the type of an assignment expression is that of its left operand. The result of the assignment operation is the value stored in the left operand after the assignment has taken place; the result is an lvalue.
有几个赋值运算符,它们都是从右到左分组的。所有都需要一个可修改的左值作为它们的左操作数,并且赋值表达式的类型是它的左操作数的类型。赋值操作的结果是赋值后左操作数中存储的值;结果是一个左值。
Your operator=
returns not only the wrong type, but not even an lvalue. Assuming GCC's error message didn't include any other candidates besides operator=(const regula::LObject&)
, GCC has simply ignored your overload entirely. The operator=
it mentions is the default, automatically generated function.
您operator=
不仅会返回错误的类型,甚至不会返回左值。假设 GCC 的错误消息除了 之外不包含任何其他候选者operator=(const regula::LObject&)
,GCC 只是完全忽略了您的重载。将operator=
它提到是默认的,自动生成功能。
On second glance, your operator[]
also should return a reference. As written, no assignment expressions like your example should work at all.
乍一看,您operator[]
还应该返回一个引用。正如所写的那样,像您的示例这样的赋值表达式根本不应该起作用。
So, you should have functions
所以,你应该有函数
LObject &LObject::operator[] (const std::string name);
and
和
template <typename T>
LObject &LObject::operator= (const T& value);