编译器使用的函数原型错误

编译器使用的函数原型错误

本文介绍了编译器使用的函数原型错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



基本上,它涉及到有两个不同的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 use const TestObjectPair (preferred solution)
  • Cast your non-const objects to const ones when needed

这篇关于编译器使用的函数原型错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-21 19:07