无法检测 T::value() 使用自动参数化 true_type
Can't detect T::value() using auto to parametrize true_type
使用 SFINAE,has_value_int<T>
和 has_value_auto<T>
都尝试检测 class T
是否有一个名为 value
的 static constexpr
函数。
- 使用
int
参数化true_type
,has_value_int<T>
适用于
演示 classes pass
和 fail
.
- 使用
auto
参数化 true_type
,has_value_auto<T>
总是 returns false。
使用 int
和使用 auto
有什么区别,为什么 auto
不起作用?
具体来说,为什么重载决策更喜欢 match_auto(...)
而不是 match_auto(int)
?
#include <iostream>
using namespace std;
// parametrize true_type
template <int> using true_int = true_type; // works
template <auto> using true_auto = true_type; // does not work
// detect if T::value() is a valid compile-time expression
template <class T> true_int<(T::value(), void(), 0)> match_int(int);
template <class T> true_auto<(T::value(), void(), 0)> match_auto(int);
template <class> false_type match_int(...); // sometimes called
template <class> false_type match_auto(...); // always called
template <class T>
static constexpr bool has_value_int = decltype(match_int<T>(0))::value;
template <class T>
static constexpr bool has_value_auto = decltype(match_auto<T>(0))::value;
template <class T>
void demo() {
cout << has_value_int<T> << "(int), " // sometimes false
<< has_value_auto<T> << "(auto)" << endl; // always false
}
int main() {
struct pass { static constexpr int value() { return 1; } };
using fail = float;
cout << "has_value<pass> = "; demo<pass>(); // 1(int), 0(auto)
cout << "has_value<fail> = "; demo<fail>(); // 0(int), 0(auto)
return 0;
}
相同
没有区别;这是一个 gcc 错误,由 Barry 报告为 #86703.
作为解决方法,不要使用函数:
// detect if T::value() is a valid compile-time expression
template <typename T, typename = void> struct match_auto : std::false_type {};
template <typename T>
struct match_auto<T, std::void_t<true_auto<(T::value(), void(), 0)>>>
: std::true_type {};
template <class T> static constexpr bool has_value_auto = match_auto<T>::value;
使用 SFINAE,has_value_int<T>
和 has_value_auto<T>
都尝试检测 class T
是否有一个名为 value
的 static constexpr
函数。
- 使用
int
参数化true_type
,has_value_int<T>
适用于 演示 classespass
和fail
. - 使用
auto
参数化true_type
,has_value_auto<T>
总是 returns false。
使用 int
和使用 auto
有什么区别,为什么 auto
不起作用?
具体来说,为什么重载决策更喜欢 match_auto(...)
而不是 match_auto(int)
?
#include <iostream>
using namespace std;
// parametrize true_type
template <int> using true_int = true_type; // works
template <auto> using true_auto = true_type; // does not work
// detect if T::value() is a valid compile-time expression
template <class T> true_int<(T::value(), void(), 0)> match_int(int);
template <class T> true_auto<(T::value(), void(), 0)> match_auto(int);
template <class> false_type match_int(...); // sometimes called
template <class> false_type match_auto(...); // always called
template <class T>
static constexpr bool has_value_int = decltype(match_int<T>(0))::value;
template <class T>
static constexpr bool has_value_auto = decltype(match_auto<T>(0))::value;
template <class T>
void demo() {
cout << has_value_int<T> << "(int), " // sometimes false
<< has_value_auto<T> << "(auto)" << endl; // always false
}
int main() {
struct pass { static constexpr int value() { return 1; } };
using fail = float;
cout << "has_value<pass> = "; demo<pass>(); // 1(int), 0(auto)
cout << "has_value<fail> = "; demo<fail>(); // 0(int), 0(auto)
return 0;
}
相同
没有区别;这是一个 gcc 错误,由 Barry 报告为 #86703.
作为解决方法,不要使用函数:
// detect if T::value() is a valid compile-time expression
template <typename T, typename = void> struct match_auto : std::false_type {};
template <typename T>
struct match_auto<T, std::void_t<true_auto<(T::value(), void(), 0)>>>
: std::true_type {};
template <class T> static constexpr bool has_value_auto = match_auto<T>::value;