问题描述
基本上,它涉及到有两个不同的getter(一个const)和非const一个)返回一个容器(在这个例子中是一个映射)与const,分别是非const value_type。
令人困惑的是,在下面的例子中编译器似乎无法在非const对象上使用const getter:
#includestdafx.h
#include< utility>
#include< map>
class TestObject
{
public:
TestObject(){}
virtual〜TestObject(){}
} ;
typedef std :: pair< const TestObject *,const TestObject *> ConstTestObjectPair;
typedef std :: pair< TestObject *,TestObject *> TestObjectPair;
class Test
{
TestObject * m_pObject;
public:
Test(){m_pObject = new TestObject();}
virtual〜Test(){delete m_pObject;}
std :: map< unsigned,ConstTestObjectPair> GetObject()const
{
std :: map< unsigned,ConstTestObjectPair>地图;
map.insert(std :: make_pair(0,std :: make_pair(m_pObject,m_pObject)));
返回地图;
}
std :: map< unsigned,TestObjectPair> GetObject()
{
std :: map< unsigned,TestObjectPair>地图;
map.insert(std :: make_pair(0,std :: make_pair(m_pObject,m_pObject)));
返回地图;
}
};
int _tmain(int argc,_TCHAR * argv [])
{
测试* pTest = new Test();
const Test * pConstTest = pTest;
std :: map< unsigned,ConstTestObjectPair> CTO = pTest-> GetObject(); //不编译,我不明白为什么!
CTO = pConstTest-> GetObject();
std :: map< unsigned,TestObjectPair> TO = pTest-> GetObject();
// TO = pConstTest-> GetObject(); //不工作,这是预期的
返回0;
}
我尝试使用VS2010和gcc,并且都不接受编译此代码。以下是VS2010返回的编译错误:
1> c:\test.cpp(48):错误C2440:初始化':不能从'std :: map< _Kty,_Ty>'转换为'std :: map< _Kty,_Ty>'
1>
1> [
1> _Kty = unsigned int,
1> _Ty = TestObjectPair
1> ]
1>和
1> [
1> _Kty = unsigned int,
1> _Ty = ConstTestObjectPair
1> ]
1>没有构造函数可以使用源类型,或构造函数重载解析是不明确的
有人可以解释为什么编译器在非const对象上找不到/使用正确的原型?
非常感谢!
如果您真的很好奇,请查看C ++ 03标准的第13.3.3节,其中介绍了如何确定最佳可行功能。这里有一些要点:
以后:
请注意,此条件中没有提到函数的返回类型。因此,非const方法被选择为最有效,因为它的隐含对象参数(本质上是this指针)是非常量的。这一切都发生在检测到返回类型的冲突之前。
要解决这个问题,我会:
- 更改您的设计,以便不需要
ConstTestObjectPair
,您可以使用const TestObjectPair
(首选解决方案) - 需要时将非const对象转换为const。
I faced a compilation problem that I do not understand, I have simplified it a bit for explanation below.
Basically, it involves having 2 different getters (a const and non-const one) that return a container (a map in this example) with const, respectively non-const value_type.
What puzzles me is that in the example below, the compiler seems unable to use the const getter on a non-const object:
#include "stdafx.h"
#include <utility>
#include <map>
class TestObject
{
public:
TestObject() {}
virtual ~TestObject() {}
};
typedef std::pair<const TestObject*, const TestObject*> ConstTestObjectPair;
typedef std::pair<TestObject*, TestObject*> TestObjectPair;
class Test
{
TestObject* m_pObject;
public:
Test() {m_pObject = new TestObject();}
virtual ~Test() {delete m_pObject;}
std::map<unsigned, ConstTestObjectPair> GetObject() const
{
std::map<unsigned, ConstTestObjectPair> map;
map.insert(std::make_pair(0, std::make_pair(m_pObject, m_pObject)));
return map;
}
std::map<unsigned, TestObjectPair> GetObject()
{
std::map<unsigned, TestObjectPair> map;
map.insert(std::make_pair(0, std::make_pair(m_pObject, m_pObject)));
return map;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
Test* pTest = new Test();
const Test* pConstTest = pTest;
std::map<unsigned, ConstTestObjectPair> CTO = pTest->GetObject(); // Not compiling, I don't get why!!!
CTO = pConstTest->GetObject();
std::map<unsigned, TestObjectPair> TO = pTest->GetObject();
//TO = pConstTest->GetObject(); // Not working, this is expected
return 0;
}
I tried with both VS2010 and gcc and neither accepts to compile this code. Here is the compilation error returned by VS2010:
1>c:\test.cpp(48): error C2440: 'initializing' : cannot convert from 'std::map<_Kty,_Ty>' to 'std::map<_Kty,_Ty>'
1> with
1> [
1> _Kty=unsigned int,
1> _Ty=TestObjectPair
1> ]
1> and
1> [
1> _Kty=unsigned int,
1> _Ty=ConstTestObjectPair
1> ]
1> No constructor could take the source type, or constructor overload resolution was ambiguous
Could someone explain me why the compiler cannot find/use the correct prototype on the non-const object?
Thanks a lot!
If you're really curious, check out section 13.3.3 of the C++03 standard, which describes how the "best viable function" is determined. Here are some important points:
And later:
Note that the return type of the function is not mentioned in this criteria. So the non-const method is selected as most valid, because its "implied object parameter" (essentially the "this" pointer) is non-const. This all happens before the conflict with the return type is detected.
To solve this problem, I would either:
- Change your design so that
ConstTestObjectPair
isn't needed, and you can just useconst TestObjectPair
(preferred solution) - Cast your non-const objects to const ones when needed
这篇关于编译器使用的函数原型错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!