使用SFINAE,has_value_int< T>和has_value_auto< T>两者都试图检测类T是否具有名为value的静态constexpr函数.
>使用int来参数化true_type,has_value_int< T>效劳于
演示类传递和失败.
>使用auto来参数化true_type,has_value_auto< T>总是返回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(),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 bug,由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(),0)>>>
- : std::true_type {};
- template <class T> static constexpr bool has_value_auto = match_auto<T>::value;