有人能解释一下这个函数的重载决策是不明确的吗?
假设:
/// 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
允许User_Type< T > user_var
T
}转换。
此外,如果我从other_function( user_var )
创建本地{{1}},那么我可以毫不含糊地呼叫{{1}}。从语义上讲,这应该等同于第一个原始陈述。
答案 0 :(得分:2)
由于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>
有ctor User_Type<char>( char const& )
,它接受int
,User_Type<int>
有ctor User_Type<int>( int const& )
,接受char
。
您的转化次数属于&#34;用户定义的转化顺序&#34;由于这两种转换都是可能的,因此两者都包含在具有相同排名的重载集中。因此,电话是模棱两可的。 (有关详细信息,请参阅标准中的13.3.3.2 排名隐式转换序列。)
答案 1 :(得分:1)
我认为这里的问题是尝试根据符合条件的转化选择过载。我可以取出一些模板并获得相同的结果:
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 */
}
问题是过载列表中没有完美的匹配,所以我们开始检查转换。反过来,char
和int
可以进行隐式转换,因此不清楚您想要哪一个。
如果对于相同的代码我更改了第一个类的构造函数
class User_Type_char
{
public:
User_Type_char(const char*) {}
};
现在,同一个调用变得明确,并调用User_Type_int版本。