How to check for static member variable template?
我需要用静态成员变量模板
下面是我想要做的一个近似值:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | #include <iostream> struct foo { template<class T> static constexpr int static_variable_template = T::constexpr_static_function(); // XXX this works but requires a second defaulted template parameter // template<class T, int = T::constexpr_static_function()> // static constexpr int static_variable_template = // T::constexpr_static_function(); }; struct has_constexpr_static_function { static constexpr int constexpr_static_function() { return 42; } }; struct hasnt_constexpr_static_function { }; template<class T, class U, int = T::template static_variable_template<U>> void test_for_static_variable_template(int) { std::cout <<"yes it has "; } template<class T, class U> void test_for_static_variable_template(...) { std::cout <<"no it hasn't "; } int main() { test_for_static_variable_template<foo, has_constexpr_static_function>(0); test_for_static_variable_template<foo, hasnt_constexpr_static_function>(0); } |
这种近似几乎可以工作,但前提是
在C++ 17中这是可能的吗?
我不确定您是否打算用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | #include <iostream> template <typename T> class has_func { typedef char does; typedef long doesnt; template <typename C> static does test( decltype(&C::constexpr_static_function) ); template <typename C> static doesnt test(...); public: static constexpr bool value() { return sizeof(test<T>(0)) == sizeof(char); } }; struct foo { template<class T> static constexpr int static_variable_template() { if constexpr (has_func<T>::value()) { return T::constexpr_static_function(); } return 0; } // XXX this works but requires a second defaulted template parameter // template<class T, int = T::constexpr_static_function()> // static constexpr int static_variable_template = // T::constexpr_static_function(); }; struct has_constexpr_static_function { static constexpr int constexpr_static_function() { return 42; } }; struct hasnt_constexpr_static_function { }; template<class T, class U> void test_for_static_variable_template(...) { if constexpr (has_func<U>::value()) { std::cout <<"yes it has "; } else { std::cout <<"no it hasn't "; } } int main() { std::cout << foo::static_variable_template<has_constexpr_static_function>() <<" "; std::cout << foo::static_variable_template<hasnt_constexpr_static_function>() <<" "; /// Original test test_for_static_variable_template<foo, has_constexpr_static_function>(0); test_for_static_variable_template<foo, hasnt_constexpr_static_function>(0); } |
印刷品
1 2 3 4 | 42 0 yes it has no it hasn't |
用
如果要完全禁用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | #include <iostream> template <typename T> class has_func { typedef char does; typedef long doesnt; template <typename C> static does test( decltype(&C::constexpr_static_function) ); template <typename C> static doesnt test(...); public: static constexpr bool value() { return sizeof(test<T>(0)) == sizeof(char); } }; struct foo { template<class T, typename std::enable_if<has_func<T>::value()>::type ...> static constexpr int static_variable_template() { if constexpr (has_func<T>::value()) { return T::constexpr_static_function(); } return 0; } // XXX this works but requires a second defaulted template parameter // template<class T, int = T::constexpr_static_function()> // static constexpr int static_variable_template = // T::constexpr_static_function(); }; struct has_constexpr_static_function { static constexpr int constexpr_static_function() { return 42; } }; struct hasnt_constexpr_static_function { }; template<class T, class U> void test_for_static_variable_template(...) { if constexpr (has_func<U>::value()) { std::cout <<"yes it has "; } else { std::cout <<"no it hasn't "; } } int main() { std::cout << foo::static_variable_template<has_constexpr_static_function>() <<" "; // We can't print this because it doesn't exist. // std::cout << foo::static_variable_template<hasnt_constexpr_static_function>() <<" "; /// Original test test_for_static_variable_template<foo, has_constexpr_static_function>(0); test_for_static_variable_template<foo, hasnt_constexpr_static_function>(0); } |
在这一思路中,我不确定是否可以使用