【发布时间】:2014-11-14 15:09:34
【问题描述】:
有人能解释一下这个函数重载决议是如何模棱两可的吗?
给定:
/// 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 )。从语义上讲,这应该等同于第一个原始语句。
【问题讨论】:
-
我觉得我以前遇到过这种情况,但我正在画一个空白。我相信它与评估模板的顺序有关,即 some_value
的返回类型在处理函数之后才推导出来,因此它是一个模棱两可的调用。与您无法将公共 typedef T some_type;添加到User_Type<T>并让编译器找出User_Type<T>::some_type是一种没有完全限定它的类型的原因相同,即typename User_Type<T>::some_type
标签: c++ implicit-conversion overloading