重载转换函数模板
Overloading conversion function templates
考虑以下几点:
struct X {
template <class T> operator T(); // #1
template <class T> operator T&(); // #2
};
int a = X{}; // error: ambiguous
int& b = X{}; // calls #2
int const& c = X{}; // calls #2
b
的情况很简单,#2
是唯一可行的候选人。什么规则表明 #2
优先于 #1
用于初始化 int const&
,但两者对于 int
的初始化有歧义?
在决定如何初始化给定初始化器的引用时,首先尝试直接绑定。 [dcl.init.ref]/(5.1.2):
If the reference is an lvalue reference and the initializer expression […] has a class type (i.e., T2
is a class type), where T1
is not reference-related to T2
, and can be
converted to an lvalue of type “cv3 T3
”, where “cv1 T1
” is reference-compatible with “cv3 T3
” (this conversion is selected by enumerating the applicable conversion functions (13.3.1.6) and choosing the best one through overload resolution (13.3)), then the reference is bound […] to the lvalue result
of the conversion […].
管理此过程的候选选择的措辞(13.3.1.6,如上所述)不包括第一个转换函数:
The conversion functions of S
and its base classes are considered. Those non-explicit conversion functions
that are not hidden within S
and yield type “lvalue reference to cv2 T2
”(when initializing an lvalue reference or an rvalue reference to function) […], where “cv1 T
” is reference-compatible (8.6.3)
with “cv2 T2
”, are candidate functions. For direct-initialization, […].
显然,这种排除是引用初始化语义所特有的,所以第一种情况仍然是模棱两可的。
考虑以下几点:
struct X {
template <class T> operator T(); // #1
template <class T> operator T&(); // #2
};
int a = X{}; // error: ambiguous
int& b = X{}; // calls #2
int const& c = X{}; // calls #2
b
的情况很简单,#2
是唯一可行的候选人。什么规则表明 #2
优先于 #1
用于初始化 int const&
,但两者对于 int
的初始化有歧义?
在决定如何初始化给定初始化器的引用时,首先尝试直接绑定。 [dcl.init.ref]/(5.1.2):
If the reference is an lvalue reference and the initializer expression […] has a class type (i.e.,
T2
is a class type), whereT1
is not reference-related toT2
, and can be converted to an lvalue of type “cv3T3
”, where “cv1T1
” is reference-compatible with “cv3T3
” (this conversion is selected by enumerating the applicable conversion functions (13.3.1.6) and choosing the best one through overload resolution (13.3)), then the reference is bound […] to the lvalue result of the conversion […].
管理此过程的候选选择的措辞(13.3.1.6,如上所述)不包括第一个转换函数:
The conversion functions of
S
and its base classes are considered. Those non-explicit conversion functions that are not hidden withinS
and yield type “lvalue reference to cv2T2
”(when initializing an lvalue reference or an rvalue reference to function) […], where “cv1T
” is reference-compatible (8.6.3) with “cv2T2
”, are candidate functions. For direct-initialization, […].
显然,这种排除是引用初始化语义所特有的,所以第一种情况仍然是模棱两可的。