为什么这个函数重载与参数类型转换不明确

Why is this function overload with argument type conversion ambiguous?

本文关键字:参数 类型转换 不明确 重载 函数 为什么      更新时间:2023-10-16

有人可以解释一下这个函数重载分辨率是如何模棱两可的吗?

鉴于:

/// This type *contains* a @c T.
template< typename T >
class User_Type
{
public:
    /// This <em>conversion constructor</em> is a key part of it's API;
    ///   it won't likely change.
    User_Type( T const & ar_data )
      : m_data( ar_data )
    {}
private:
    T m_data;
};
/// @c some_value is just a templated function that generates a @c T.
template< typename T > T some_value();
template<> char some_value();
template<> int some_value();
/// This overloaded, non-templated function represents some third-party
///   code somewhere else; it's API can't be changed.
void other_function( User_Type< char > const& );
void other_function( User_Type< int > const& );
/// This is user-code.  It's contents exercise some aspect of the 'User_Type' API.
///   This code can change.
template< typename T >
void function()
{
    other_function( some_value< T >() ); /* AMBIGUOUS CALL */
    User_Type< T > user_var = some_value< T >(); /* UNAMBIGUOUS CONVERSION */
    other_function( user_var ); /* UNAMBIGUOUS CALL */
}
template void function< char >();
template void function< int >();

并使用g++-4.9 -Wall -Wextra进行编译,我收到以下错误:

In instantiation of ‘void function() [with T = char]’:
    error: call of overloaded ‘other_function(char)’ is ambiguous
    note: candidates are:
    note: void other_function(const User_Type<char>&)
    note: void other_function(const User_Type<int>&)
In instantiation of ‘void function() [with T = int]’:
    error: call of overloaded ‘other_function(int)’ is ambiguous
    note: candidates are:
    note: void other_function(const User_Type<char>&)
    note: void other_function(const User_Type<int>&)

我希望other_function( char )的最佳匹配是other_function( User_Type< char > const& ),而other_function( int )的最佳匹配是other_function( User_Type< int > const& )

我知道每个参数都必须进行类型转换才能other_function. 我希望char User_Type< char >是比char User_Type< int >更好的选择,char可以允许int晋升。 我希望int User_Type< int >是比int User_type< char >更好的选择,int可以允许char转换。

此外,如果我从T创建本地User_Type< T > user_var,那么我可以明确地调用other_function( user_var )。 从语义上讲,这应该等效于第一个原始语句。

由于没有完全匹配的other_function(char)other_function(int)

other_function( some_value< T >() );

必须隐式转换其参数以匹配以下参数之一:

void other_function( User_Type< char > const& );
void other_function( User_Type< int > const& );

但是User_Type<char>有接受int的 CTOR User_Type<char>( char const& )User_Type<int>有接受char的 CTOR User_Type<int>( int const& )

您的转化属于"用户定义的转化序列"的排名,并且由于这两种转化都是可能的,因此两者都包含在排名相等的重载集中。因此,该调用是模棱两可的。(有关详细信息,请参阅 13.3.3.2 在标准中对隐式转换序列进行排名

我认为这里的问题是试图根据合格的转换来选择重载。 我可以取出一些模板并获得相同的结果:

class User_Type_char
{
public:
    User_Type_char(char const &) {}
};
class User_Type_int
{
public:
    User_Type_int(int const &) {}
};
void other_function( User_Type_char const& );
void other_function( User_Type_int const& );
template< typename T >
void function()
{
    other_function( 'a' ); /* AMBIGUOUS CALL */
}

问题是重载列表中没有完全匹配,因此我们开始检查转换。 但是,反过来,charint都有隐式转换可用,因此不清楚您想要哪一个。

如果对于相同的代码,我更改了第一个类的构造函数

class User_Type_char
{
public:
    User_Type_char(const char*) {}
};

现在,相同的调用变得明确并调用User_Type_int版本。