为什么重载决议不 select 更专门用于默认的单个模板参数
Why the overload resolution doesn't select the more specialised for a defaulted single template parameter
使用 2 个模板参数,第二个作为默认参数,当专业化导致显式提供第二个参数的默认类型时,我得到了我所期望的。在这种情况下,专业化形成良好,因为它更专业化,所以它被选中。
当我仅使用一个模板参数(也默认)重复这一点时,专业化似乎仍然结构良好,明确提供了基本模板中默认的类型。然而,在这种情况下,这似乎被忽略了,并且没有被认为更专业。始终选择基本版本。
有人可以解释为什么会这样吗?
#include <iostream>
#include <utility>
#include <type_traits>
struct F1 { int operator()(); };
struct F2 {};
template<typename T, typename = int> struct A { constexpr static bool function_call_operator{false}; };
template<typename T> struct A<T, decltype(std::declval<T>()())> { constexpr static bool function_call_operator{true}; };
template<typename T = int> struct B { constexpr static bool function_call_operator{false}; };
template<typename T> struct B<decltype(std::declval<T>()())> { constexpr static bool function_call_operator{true}; };
void f0() {}
int main() {
std::cout << std::boolalpha;
std::cout << A<F1>::function_call_operator << std::endl; // true; OK
std::cout << A<F2>::function_call_operator << std::endl; // false; OK
std::cout << B<F1>::function_call_operator << std::endl; // false; why ?
std::cout << B<F2>::function_call_operator << std::endl; // false; OK
std::cout << std::noboolalpha;
}
Here's the online 使用 C++14 编译器编译的版本。
When I repeat that with just one template argument, also defaulted, the specialisation seems to be still well formed, explicitly supplying the type which is otherwise default in the base template. However in this case it seems that this is ignored and not considered more specialised. The base version is always chosen.
因为 B
的专业化是 int
(在 F1
和 F2
情况下)
template <typename T>
struct B<decltype(std::declval<T>()())> // decltype(...) is int, in F1 and F2 cases
{ constexpr static bool function_call_operator{true}; };
您用 F1
和 F2
实例化 B
。它们都不同于 int
.
只有通用版本同时匹配 B<F1>
和 B<F2>
。
永远不会选择 B
专业化,因为 T
不可推导(从 B<int>
你不能推导 F1
或 F2
)。
使用 2 个模板参数,第二个作为默认参数,当专业化导致显式提供第二个参数的默认类型时,我得到了我所期望的。在这种情况下,专业化形成良好,因为它更专业化,所以它被选中。
当我仅使用一个模板参数(也默认)重复这一点时,专业化似乎仍然结构良好,明确提供了基本模板中默认的类型。然而,在这种情况下,这似乎被忽略了,并且没有被认为更专业。始终选择基本版本。
有人可以解释为什么会这样吗?
#include <iostream>
#include <utility>
#include <type_traits>
struct F1 { int operator()(); };
struct F2 {};
template<typename T, typename = int> struct A { constexpr static bool function_call_operator{false}; };
template<typename T> struct A<T, decltype(std::declval<T>()())> { constexpr static bool function_call_operator{true}; };
template<typename T = int> struct B { constexpr static bool function_call_operator{false}; };
template<typename T> struct B<decltype(std::declval<T>()())> { constexpr static bool function_call_operator{true}; };
void f0() {}
int main() {
std::cout << std::boolalpha;
std::cout << A<F1>::function_call_operator << std::endl; // true; OK
std::cout << A<F2>::function_call_operator << std::endl; // false; OK
std::cout << B<F1>::function_call_operator << std::endl; // false; why ?
std::cout << B<F2>::function_call_operator << std::endl; // false; OK
std::cout << std::noboolalpha;
}
Here's the online 使用 C++14 编译器编译的版本。
When I repeat that with just one template argument, also defaulted, the specialisation seems to be still well formed, explicitly supplying the type which is otherwise default in the base template. However in this case it seems that this is ignored and not considered more specialised. The base version is always chosen.
因为 B
的专业化是 int
(在 F1
和 F2
情况下)
template <typename T>
struct B<decltype(std::declval<T>()())> // decltype(...) is int, in F1 and F2 cases
{ constexpr static bool function_call_operator{true}; };
您用 F1
和 F2
实例化 B
。它们都不同于 int
.
只有通用版本同时匹配 B<F1>
和 B<F2>
。
永远不会选择 B
专业化,因为 T
不可推导(从 B<int>
你不能推导 F1
或 F2
)。