使用 auto 重载模板函数的解析
overload resolution of template function with auto
使用以下 3 个重载
template <class T> auto foo() { return 1; }
template <class T> int foo() { return 2; }
template <class T> T foo() { return 3; }
下面的格式不正确吗?
static_cast<int(*)()>(&foo<int>)();
Clang selects 重载 #2,而 gcc 无法编译 (Demo)
删除重载 #1 时,双方都同意 select 重载 #2 (Demo)。
删除重载 #2 时,gcc selects 重载 #1 并且 clang 无法编译 (Demo)
根据[over.over]/2, we perform template argument deduction. This will succeed for all three overloads: in the first one, keep [temp.deduct.funcaddr]/2记:
A placeholder type (7.1.7.4) in the return type of a function template is a non-deduced context. If template
argument deduction succeeds for such a function, the return type is determined from instantiation of the
function body.
由于推导会成功(假设所有模板参数都显式提供了参数),return 类型被推导为 int
。在第二种情况下,推导成功,因为提供了参数,而在第三种情况下,将推导 T
。 †
继续 paragraph 4、
If more than one function is selected, [...] any given
function template specialization F1
is eliminated if the set contains
a second function template specialization whose function template is
more specialized than the function template of F1
according to the
partial ordering rules of 14.5.6.2. After such eliminations, if any, there shall remain exactly one selected function.
根据 [temp.deduct.partial]/3, the function templates' function types are used for partial ordering. We can immediately see that #1 and #2's function types do not contain any template parameters that participate in deduction, hence via the addition to [temp.deduct.partial]/4 introduced by core issue 1391's resolution, their corresponding P
s are not used to determine the ordering. @bogdan explained 为什么该决议有问题;最重要的是,排序只会产生#1 和#2 的歧义。
也就是说,根据当前(可能有缺陷的)措辞,转换在所有情况下都是错误格式的。如果 non-dependent/deducing 参数对的偏序是固定的,
- 情况 1 和 3 是不明确的,因为对于两个非依赖函数类型(#1 和 #2 的函数类型),没有顺序对。
- 案例 2 中的接受行为是正确的(如预期的那样)。
† [temp.deduct.type]/8元素9(T()
),以防你好奇。
使用以下 3 个重载
template <class T> auto foo() { return 1; }
template <class T> int foo() { return 2; }
template <class T> T foo() { return 3; }
下面的格式不正确吗?
static_cast<int(*)()>(&foo<int>)();
Clang selects 重载 #2,而 gcc 无法编译 (Demo)
删除重载 #1 时,双方都同意 select 重载 #2 (Demo)。
删除重载 #2 时,gcc selects 重载 #1 并且 clang 无法编译 (Demo)
根据[over.over]/2, we perform template argument deduction. This will succeed for all three overloads: in the first one, keep [temp.deduct.funcaddr]/2记:
A placeholder type (7.1.7.4) in the return type of a function template is a non-deduced context. If template argument deduction succeeds for such a function, the return type is determined from instantiation of the function body.
由于推导会成功(假设所有模板参数都显式提供了参数),return 类型被推导为 int
。在第二种情况下,推导成功,因为提供了参数,而在第三种情况下,将推导 T
。 †
继续 paragraph 4、
If more than one function is selected, [...] any given function template specialization
F1
is eliminated if the set contains a second function template specialization whose function template is more specialized than the function template ofF1
according to the partial ordering rules of 14.5.6.2. After such eliminations, if any, there shall remain exactly one selected function.
根据 [temp.deduct.partial]/3, the function templates' function types are used for partial ordering. We can immediately see that #1 and #2's function types do not contain any template parameters that participate in deduction, hence via the addition to [temp.deduct.partial]/4 introduced by core issue 1391's resolution, their corresponding P
s are not used to determine the ordering. @bogdan explained
也就是说,根据当前(可能有缺陷的)措辞,转换在所有情况下都是错误格式的。如果 non-dependent/deducing 参数对的偏序是固定的,
- 情况 1 和 3 是不明确的,因为对于两个非依赖函数类型(#1 和 #2 的函数类型),没有顺序对。
- 案例 2 中的接受行为是正确的(如预期的那样)。
† [temp.deduct.type]/8元素9(T()
),以防你好奇。