【问题标题】:ambiguous call to overloaded function - int and int&对重载函数的模糊调用 - int 和 int&
【发布时间】:2012-11-13 20:44:18
【问题描述】:
void g(int& a)
{
    std::cout<<"int&\n";
} 

void g(int a)
{
    std::cout<<"int\n";
}  

int main()
{    
    int a = 2;   
    g(a); //won't compile (at least under MSVC 2012)

    std::cin.ignore();
}

有没有办法在这里避免模棱两可的调用错误?类似g( static_cast&lt;int&amp;&gt;(a) );

【问题讨论】:

  • 想要它调用哪一个?
  • g( static_cast&lt;int&amp;&gt;(a) ); 我希望g(int&amp; a) 被调用

标签: c++ reference overloading


【解决方案1】:

如果你可以施法,当然有办法消除通话歧义:

g(const_cast<int const&>(a));

如果非要调用参考版,分辨率就有点棘手了:

static_cast<void(*)(int&)>(g)(a);

【讨论】:

  • +1 表示转换为const(我什至没有想到!),但-1 表示使用static_cast 而不是const_cast,总之,0。 -)
  • @Cheersandhth.-Alf:好点:我会修正答案以使用正确的演员表!
  • static_cast&lt;void(*)(int&amp;)&gt;(g)(a);: 你必须喜欢一门像 C++ 这样简单的语言:) (+1)
  • 啊,令人兴奋 - 那么static_cast&lt;int&amp;&amp;&gt;(a) 也应该可以工作,不是吗?
  • 是的,int 会的。如果类型不是int,而是std::string,则此使用将移动对象,这可能不完全符合您的要求。
【解决方案2】:

这个答案与我回答时的问题有关。

OP 不断补充问题,我不会追究...


是的,是的,你是对的,它涉及强制转换以解决歧义:

#include <iostream>

void g(int& a)
{
    std::cout<<"int&\n";
} 

void g(int a)
{
    std::cout<<"int\n";
}  

int main()
{    
    int a = 2;   
    static_cast< void(*)(int&) >( g )( a );
}

注意:要在 Visual Studio 中运行它并查看结果窗口,请使用 [Ctrl F5],或在 main 的最后一个右大括号上放置一个断点并在调试器中运行它。但更好的是,只需从命令行运行它。无需在末尾添加“停止”! :-)


修正Dietmar showed in his answer 如何使用转换为 const 来调用按值参数重载。我什至没有想到这一点,但如果你想这样做(仅限于从考虑中删除引用版本),请使用const_cast 而不是static_cast

或者更好,只需从参数中创建一个右值表达式,例如通过在前面添加一个方便的小+ 标志,

    g( +a );

:-)

【讨论】:

  • 确实可以像这样禁用重载解析,但这并不理想。永远不可能在这样的左值上调用裸函数...
  • kerrek,我无法理解您的评论。它认为这意味着它毫无意义。例如,它几乎不是“理想的”,那么为什么要对我而不是向要求这个的 OP 发表评论。或者为什么不自己做,因为你在我向你展示时添加了这个解决方案。天哪。
  • @downvoter(kerrek,是你吗?),请解释你的反对意见,以便人们更容易看到你是谁。
  • 不是我,当然不是——我基本上复制了你的答案以使我的答案完整;-)
  • 有什么难过的?我发表了评论,以便 OP 可以发现虽然他的问题确实有直接答案,但生成的代码不会很好。
【解决方案3】:

出于重载决议的目的,绑定到正确类型的引用是完全匹配的,就像绑定到正确类型的非引用一样,因此两个重载相对于左值 @987654323 具有相同的优先级@参数。

可以使第二个重载采用int const &amp;,在这种情况下,它可以以完全相同的方式使用,但将是一个不同的重载。

或者,您可以通过转换 function 类型来完全避免重载决议:

static_cast<void(&)(int)>(g)(a);
static_cast<void(&)(int&)>(g)(a);

您必须在每次调用存在歧义的函数时执行此操作(即,当传递左值 int 时)。

这个视频是mandatory viewing给你的。

【讨论】:

  • 您的回答在技术上仍然不正确,所以我保留反对票。
  • “这两个重载总是具有相同的优先级”不遵循前面的论点,因为它们并不总是具有“正确的类型”wrt。实际参数,特别是const 或右值参数。特别是,dietmar 的回答显示了一种纯粹通过实际参数的类型选择按值函数的方法,而我的回答显示了另一种选择按值参数的方法,纯粹通过实际参数表达式的右值。我觉得我的回答更可爱,顺便说一句。它肯定是最短和最清晰的函数调用 :-)
  • @Cheersandhth.-Alf:哦,当然,我现在看到了。 int 重载当然可以在更一般的情况下工作。我会改写。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-11
  • 2011-12-12
  • 2014-09-05
  • 1970-01-01
相关资源
最近更新 更多