Call function, if there is, ignore otherwise
本问题已经有最佳答案,请猛点这里访问。
我现在想制作模板,将一些元素推送到向量和其他类型,这些类型支持
我可以这样做
1 2 3 4 5 6 7 8 9 | template<typename T> T fill(size_t n) { T v; //(1) for(size_t i = 0; i < n; ++i){ v.push_back(generate_some_how()); } return v; } |
它起作用了。但现在,我想提高使用
实现这一目标是否容易?
我知道我可能专门研究硬编码类型,但似乎不太好。
C++ 11是可以的。
使用C++ 11的一个简单示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | template<class T> auto maybe_reserve(T& v, size_t n, int) -> decltype(v.reserve(n), void()) { v.reserve(n); } template<class T> void maybe_reserve(T&, size_t, long){} template<typename T> T fill(std::size_t n) { T v; maybe_reserve(v, n, 0); for(size_t i = 0; i < n; ++i){ v.push_back(generate_some_how()); } return v; } |
活生生的例子。解释请看这里。
C++ 11中的一种可能方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | template<typename T, typename = void> struct reserve_helper { static void call(T& obj, std::size_t s) { } }; template<typename T> struct reserve_helper<T, decltype(std::declval<T>().reserve(0), void(0))> { static void call(T& obj, std::size_t s) { obj.reserve(s); } }; template<typename T> T fill(std::size_t n) { T v; reserve_helper<T>::call(v, 10); for(std::size_t i = 0; i < n; ++i){ v.push_back(generate_somehow()); } return v; } |
下面是一个实况示例,它显示对
不太难……您需要编写一个特征来检测具有正确签名的保留成员函数的存在。有了这个工具,有了不同的方法,您就可以编写一个
检测是否在C++ 03中存在EDCOX1×4成员函数:
1 2 3 4 5 6 7 8 9 10 | template <typename T> struct has_reserve { typedef char yes; typedef yes no[2]; template <typename U, U> struct ptrmbr_to_type; template <typename U> static yes& test(ptrmbr_to_type<void (T::*)(std::size_t),&U::reserve>*); template <typename U> static no& test(...); static const bool value = sizeof(test<T>(0))==sizeof(yes); }; |