【问题标题】:ambiguous call to overloaded function对重载函数的模糊调用
【发布时间】:2012-02-21 12:26:06
【问题描述】:

我有两个功能:

void DoSomething( const tchar* apsValue )
void DoSomething( size_t aiValue )

现在我想将 '0' 作为 size_t 传递:

DoSomething(0);

编译器抛出错误:“对重载函数的模糊调用”

为了解决这个问题,我可以使用 static_cast,例如:

DoSomething(static_cast<size_t>(0));

或者简单:

DoSomething(size_t(0));

其中一个比另一个更好吗?有没有其他方法可以解决这个问题?

【问题讨论】:

  • static_cast 在任何时候都比适用的 c-style cast 更好。
  • @iammilind size_t(0) 不是 c 风格的演员表。它构造了一个以 '0' 为值的新 size_t
  • @iammilind 为什么? static_cast 比 C 风格转换更可取,在这种转换可能存在 C 风格转换解析为什么类型的问题:指针或引用。否则......当你想要一个MyClass 的临时实例时,你会写static_cast&lt; MyClass &gt;( 42 )MyClass( 42 ) 吗?
  • 在这种特定情况下,您可能可以为 size_t 写DoSomething(0u),但这不是类似情况的通用解决方案。
  • @JamesKanze, ...where it is applicable

标签: c++ overloading static-cast


【解决方案1】:

这是模棱两可的,因为 0 的类型为 int,而不是 size_t。它可以转换 到 size_t 或指针,所以如果你有两者的重载, 这是模棱两可的。一般来说,如果你有 重载函数,其中一个可以采用整数类型,您可以添加 int 的重载,可能类似于:

inline void DoSomething( int aiValue )
{
    DoSomething( static_cast<size_t>( aiValue ) );
}

默认情况下,整型文字的类型为 int(除非它们太大而无法 适合int),并且通过提供完全匹配,您可以避免任何 模棱两可。

【讨论】:

    【解决方案2】:
    #include <iostream>
    #include <stddef.h>
    using namespace std;
    
    void DoSomething( char const* apsValue ) { cout << "ptr" << endl; }
    void DoSomething( size_t aiValue ) { cout << "int" << endl;}
    
    template< class Type > Type runtime_value( Type v ) { return v; }
    int null() { return 0; }
    template< class Type > Type* nullPointerValue() { return 0; }
    
    int main()
    {
        // Calling the integer argument overload:
        int dummy = 0;
        DoSomething( size_t() );
        DoSomething( runtime_value( 0 ) );
        DoSomething( null( ) );
        DoSomething( dummy );
        static_cast< void(*)( size_t ) >( DoSomething )( 0 );
    
        // Calling the pointer argument overload:
        DoSomething( nullptr );
        DoSomething( nullPointerValue<char>() );
        static_cast< void(*)( char const* ) >( DoSomething )( 0 );
    }
    

    这似乎令人惊讶,但它不仅仅是隐式类型转换在起作用。这也是一个整数类型的编译时间常数 0 隐式转换为空指针。例如,null() 函数避免了这种情况,因为结果不是编译时间常数。

    【讨论】:

      【解决方案3】:

      不明确的原因:NULL 的数值为 0

      如果您在传递0 作为参数时想要void DoSomething( const tchar* apsValue )nullptr 将很有帮助。 检查这个What exactly is nullptr?

      【讨论】:

      • 但是NULL 不是这个问题模棱两可的原因; 0 是。新的nullptr 在这里无济于事,因为我们的目标是无论如何都不会调用函数的指针版本。
      • 同意!但是编译器发现它模棱两可,因为它可能是 NULL 的值,或者只是 int,其值为 0。我会尝试改写它。
      猜你喜欢
      • 1970-01-01
      • 2020-05-11
      • 2011-12-12
      • 2014-09-05
      • 2016-03-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多