Boost中Core模組的enable_if用法及說明
阿新 • • 發佈:2018-11-24
標頭檔案
boost/utility/enable_if.hpp
作用
enable_if,lazy_enable_if,disable_if,lazy_disable_if 作用說明
enable_if 說明
template <class Cond, class T = void>
struct enable_if : public enable_if_c<Cond::value, T> {};
當Cond::value為真,enable_if,才會有型別type,且type為 T型別。
lazy_enable_if 說明
template <class Cond, class T> struct lazy_enable_if : public lazy_enable_if_c<Cond::value, T> {};
當Cond::value為真,lazy_enable_if,才會有型別T::type,常常與boost其他模組搭配使用。
disable_if 說明
template <class Cond, class T = void>
struct disable_if : public disable_if_c<Cond::value, T> {};
當Cond::value為假,disable_if,才會有型別type,且type為 T型別。
lazy_disable_if 說明
template <class Cond, class T> struct lazy_disable_if : public lazy_disable_if_c<Cond::value, T> {};
當Cond::value為假,lazy_disable_if,才會有型別T::type,常常與boost其他模組搭配使用。
enable_if,lazy_enable_if,disable_if,lazy_disable_if ,從本質上說,都是為了將不符合要求的引數剔除,傳遞了不符合要求的引數,在編譯期間會報錯。常常用於 模板類或模板函式的型參 型別,或者是 返回值 型別。
舉例
enable_if,disable_if模板類 建構函式 型參
#include <boost/utility/enable_if.hpp> #include <boost/type_traits.hpp> #include <boost/detail/lightweight_test.hpp> using boost::enable_if; using boost::disable_if; using boost::is_arithmetic; struct container { bool my_value; template <class T> container(const T&, const typename enable_if<is_arithmetic<T>, T>::type * = 0): my_value(true) {} template <class T> container(const T&, const typename disable_if<is_arithmetic<T>, T>::type * = 0): my_value(false) {} }; // example from Howard Hinnant (tests enable_if template members of a templated class) template <class charT> struct xstring { template <class It> xstring(It begin, It end, typename disable_if<is_arithmetic<It> >::type* = 0) : data(end-begin) {} int data; }; int main() { BOOST_TEST(container(1).my_value); BOOST_TEST(container(1.0).my_value); BOOST_TEST(!container("1").my_value); BOOST_TEST(!container(static_cast<void*>(0)).my_value); char sa[] = "123456"; BOOST_TEST(xstring<char>(sa, sa+6).data == 6); return boost::report_errors(); }
enable_if,disable_if模板函式 返回值
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_arithmetic.hpp>
#include <boost/detail/lightweight_test.hpp>
using boost::enable_if;
using boost::disable_if;
using boost::is_arithmetic;
template <int N> struct dummy {
dummy(int) {};
};
template<class T>
typename enable_if<is_arithmetic<T>, bool>::type
arithmetic_object(T t, dummy<0> = 0) { return true; }
template<class T>
typename disable_if<is_arithmetic<T>, bool>::type
arithmetic_object(T t, dummy<1> = 0) { return false; }
int main()
{
BOOST_TEST(arithmetic_object(1));
BOOST_TEST(arithmetic_object(1.0));
BOOST_TEST(!arithmetic_object("1"));
BOOST_TEST(!arithmetic_object(static_cast<void*>(0)));
return boost::report_errors();
}
lazy_enable_if
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/detail/lightweight_test.hpp>
using boost::lazy_enable_if;
using boost::lazy_disable_if;
using boost::lazy_enable_if_c;
using boost::lazy_disable_if_c;
template <class T>
struct is_int_or_double {
BOOST_STATIC_CONSTANT(bool,
value = (boost::is_same<T, int>::value ||
boost::is_same<T, double>::value));
};
template <class T>
struct some_traits {
typedef typename T::does_not_exist type;
};
template <>
struct some_traits<int> {
typedef bool type;
};
template <>
struct some_traits<double> {
typedef bool type;
};
template <class T>
struct make_bool {
typedef bool type;
};
template <>
struct make_bool<int> {};
template <>
struct make_bool<double> {};
namespace A {
template<class T>
typename lazy_enable_if<is_int_or_double<T>, some_traits<T> >::type
foo(T t) { return true; }
template<class T>
typename lazy_enable_if_c<is_int_or_double<T>::value, some_traits<T> >::type
foo2(T t) { return true; }
}
namespace B {
template<class T>
typename lazy_disable_if<is_int_or_double<T>, make_bool<T> >::type
foo(T t) { return false; }
template<class T>
typename lazy_disable_if_c<is_int_or_double<T>::value, make_bool<T> >::type
foo2(T t) { return false; }
}
int main()
{
using namespace A;
using namespace B;
BOOST_TEST(foo(1));
BOOST_TEST(foo(1.0));
BOOST_TEST(!foo("1"));
BOOST_TEST(!foo(static_cast<void*>(0)));
BOOST_TEST(foo2(1));
BOOST_TEST(foo2(1.0));
BOOST_TEST(!foo2("1"));
BOOST_TEST(!foo2(static_cast<void*>(0)));
return boost::report_errors();
}
原始碼
namespace boost
{
template<typename T, typename R=void>
struct enable_if_has_type
{
typedef R type;
};
template <bool B, class T = void>
struct enable_if_c {
typedef T type;
};
template <class T>
struct enable_if_c<false, T> {};
template <class Cond, class T = void>
struct enable_if : public enable_if_c<Cond::value, T> {};
template <bool B, class T>
struct lazy_enable_if_c {
typedef typename T::type type;
};
template <class T>
struct lazy_enable_if_c<false, T> {};
template <class Cond, class T>
struct lazy_enable_if : public lazy_enable_if_c<Cond::value, T> {};
template <bool B, class T = void>
struct disable_if_c {
typedef T type;
};
template <class T>
struct disable_if_c<true, T> {};
template <class Cond, class T = void>
struct disable_if : public disable_if_c<Cond::value, T> {};
template <bool B, class T>
struct lazy_disable_if_c {
typedef typename T::type type;
};
template <class T>
struct lazy_disable_if_c<true, T> {};
template <class Cond, class T>
struct lazy_disable_if : public lazy_disable_if_c<Cond::value, T> {};
} // namespace boost