C ++重载决策规则的缺陷?

时间:2016-02-25 17:23:09

标签: c++ templates namespaces language-lawyer overload-resolution

请考虑以下代码:

import flash.display.Sprite; 
import flash.text.*;
import flash.display.MovieClip;
import flash.events.MouseEvent;
var success:Boolean = false;
var butpic1:SimpleButton;
butpic1.enabled = true;
addChild(butpic1);

butpic1.addEventListener(MouseEvent.CLICK, clickpics);

function clickpics(event:MouseEvent):void {
gotoAndPlay(1);
var myTextBox:TextField = new TextField();    
    myTextBox.text = "Σωστό Συνέχισε!";  
myTextBox.border = true;    
    myTextBox.borderColor = 0x000000; 
myTextBox.width = 180;    
myTextBox.height = 87;    
myTextBox.x = -77;    
myTextBox.y = -126; 
var myFormat:TextFormat = new TextFormat(); 
myFormat.color = 000000;    
    myFormat.size = 24;
myFormat.align = TextFormatAlign.CENTER
myTextBox.background = true;    
myTextBox.backgroundColor = 0xFFF000;
myTextBox.setTextFormat(myFormat);
    addChild(myTextBox);  

/*var Success=true;*/
//MovieClip(parent).Success2();
//trace(event.target.name);
var success=true;
if(MovieClip(root).butpic3 && butpic1 == success)
    {

    MovieClip(root).gotoAndPlay("win");
    } 
//checking();
//trace(event.target);
//MovieClip(this.parent).success2();
//checking();
//MovieClip(root).check();
//trace("click: " + event.currentTarget.name);
}
//trace(MovieClip(root).but.butpic2);
/*function checking():void
{
if(butpic1 && MovieClip(root).butt.butpic3)
    {
    MovieClip(parent).gotoAndPlay("win");
    } else {
MovieClip(parent).gotoAndPlay("win");
}
}*/

/*function checking():void
{
if(MovieClip(root).Symbol1 && MovieClip(root).button2)
    {

    MovieClip(parent).gotoAndPlay("win");
    } 
}*/

根据标准,编译失败并出现“模糊过载错误”。

但为什么呢?当然,A''home'命名空间中“同样好”的运算符应该优先?有没有合理的理由不这样做?

2 个答案:

答案 0 :(得分:10)

如果您希望namespace A中的重载优先于您必须添加内容以使其更好。说,使它不是模板:

namespace ns1 
{
    std::ostream& operator<<(std::ostream&, const A& );
}

否则,实际上没有概念上的理由可以看出为什么一个命名空间中的函数模板优先于另一个命名空间中的函数模板,如果两者完全等效的话。毕竟,为什么A命名空间中的函数模板比​​f命名空间中的函数模板“更好”? f“的实施者不会更清楚”吗?“完全依靠功能签名来回避这个问题。

答案 1 :(得分:0)

如果您仔细阅读编译器错误,则operator<<ns1中的ns2版本之间,以及operator<<(os, const char*) ns1实例化版本之间不存在歧义错误1}}和来自namespace std的完全相同的重载。后者被std::ostream的ADL拖入。

最好的方法是使用@Barry的建议,并对名称空间operator<<中的ns1进行去模糊处理,同时添加与ns1::A相关的所有功能(例如{ {1}})进入相同的命名空间:

f(A)

Live Example

命名空间#include <iostream> namespace ns1 { struct A {}; std::ostream& operator << (std::ostream& os, const A& t) { return os << "ns1::print" << std::endl; } void f (const A& a) { std::cout << a; } } int main() { ns1::A a; f(a); // rely on ADL to find ns1::operator<<(os, A) } 然后通过ADL充当ns1的更广泛接口。