编译器使用的函数原型错误? [英] Wrong function prototype used by compiler?

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

问题描述



基本上,它涉及到有两个不同的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:

The selection criteria for the best function are the number of arguments, how well the arguments match the types of the parameters of the candidate function, how well (for nonstatic member functions) the object matches the implied object parameter, and certain other properties of the candidate function. [Note: the function selected by overload resolution is not guaranteed to be appropriate for the context. Other restrictions, such as the accessibility of the function, can make its use in the calling context ill-formed. ]

And later:

If there is exactly one viable function that is a better function than all other viable functions, then it is the one selected by overload resolution

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

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

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆