Boost中Core模組的ref用法
阿新 • • 發佈:2018-12-03
標頭檔案
boost/core/ref.hpp
作用
能夠將 基本資料型別及自定義類,進行 包裝,及解引用;還可以對函式進行 包裝,及解引用
主要API:boost::ref,boost::cref,boost::is_reference_wrapper,boost::unwrap_reference
主要巨集:BOOST_TEST_REF,BOOST_TEST_CREF
舉例
基本資料型別包裝
#include <boost/ref.hpp> #include <boost/core/is_same.hpp> #include <boost/static_assert.hpp> #include <boost/detail/workaround.hpp> namespace { template< typename T, typename U > void ref_test(boost::reference_wrapper<U>) { typedef typename boost::reference_wrapper<U>::type type; BOOST_STATIC_ASSERT((boost::core::is_same<U,type>::value)); BOOST_STATIC_ASSERT((boost::core::is_same<T,type>::value)); } } // namespace int main() { int i = 0; int& ri = i; int const ci = 0; int const& rci = ci; // 'ref/cref' functions test ref_test<int>(boost::ref(i)); ref_test<int>(boost::ref(ri)); ref_test<int const>(boost::ref(ci)); ref_test<int const>(boost::ref(rci)); return 0; }
基本資料型別 const包裝
#include <boost/ref.hpp> #include <boost/core/is_same.hpp> #include <boost/static_assert.hpp> #include <boost/detail/workaround.hpp> namespace { template< typename T, typename U > void ref_test(boost::reference_wrapper<U>) { typedef typename boost::reference_wrapper<U>::type type; BOOST_STATIC_ASSERT((boost::core::is_same<U,type>::value)); BOOST_STATIC_ASSERT((boost::core::is_same<T,type>::value)); } } // namespace int main() { int i = 0; int& ri = i; int const ci = 0; int const& rci = ci; ref_test<int const>(boost::cref(i)); ref_test<int const>(boost::cref(ri)); ref_test<int const>(boost::cref(ci)); ref_test<int const>(boost::cref(rci)); return 0; }
包裝型別 賦值
#include <boost/ref.hpp> #include <boost/core/is_same.hpp> #include <boost/static_assert.hpp> #include <boost/detail/workaround.hpp> namespace { template< typename T > void assignable_test(T x) { x = x; } } // namespace int main() { int i = 0; int& ri = i; int const ci = 0; int const& rci = ci; // test 'assignable' requirement assignable_test(boost::ref(i)); assignable_test(boost::ref(ri)); assignable_test(boost::cref(i)); assignable_test(boost::cref(ci)); assignable_test(boost::cref(rci)); return 0; }
包裝型別 判斷
#include <boost/ref.hpp>
#include <boost/core/is_same.hpp>
#include <boost/static_assert.hpp>
#include <boost/detail/workaround.hpp>
namespace {
template< bool R, typename T >
void is_reference_wrapper_test(T)
{
BOOST_STATIC_ASSERT(boost::is_reference_wrapper<T>::value == R);
}
} // namespace
int main()
{
int i = 0;
int& ri = i;
int const ci = 0;
int const& rci = ci;
// 'is_reference_wrapper' test
is_reference_wrapper_test<true>(boost::ref(i));
is_reference_wrapper_test<true>(boost::ref(ri));
is_reference_wrapper_test<true>(boost::cref(i));
is_reference_wrapper_test<true>(boost::cref(ci));
is_reference_wrapper_test<true>(boost::cref(rci));
is_reference_wrapper_test<false>(i);
is_reference_wrapper_test<false, int&>(ri);
is_reference_wrapper_test<false>(ci);
is_reference_wrapper_test<false, int const&>(rci);
return 0;
}
包裝型別 解引用
#include <boost/ref.hpp>
#include <boost/core/is_same.hpp>
#include <boost/static_assert.hpp>
#include <boost/detail/workaround.hpp>
namespace {
template< typename R, typename Ref >
void unwrap_reference_test(Ref)
{
typedef typename boost::unwrap_reference<Ref>::type type;
BOOST_STATIC_ASSERT((boost::core::is_same<R,type>::value));
}
} // namespace
int main()
{
int i = 0;
int& ri = i;
int const ci = 0;
int const& rci = ci;
// 'unwrap_reference' test
unwrap_reference_test<int>(boost::ref(i));
unwrap_reference_test<int>(boost::ref(ri));
unwrap_reference_test<int const>(boost::cref(i));
unwrap_reference_test<int const>(boost::cref(ci));
unwrap_reference_test<int const>(boost::cref(rci));
unwrap_reference_test<int>(i);
unwrap_reference_test<int>(ri);
unwrap_reference_test<int>(ci);
unwrap_reference_test<int>(rci);
unwrap_reference_test<int&, int&>(i);
unwrap_reference_test<int&, int&>(ri);
unwrap_reference_test<int const&, int const&>(i);
unwrap_reference_test<int const&, int const&>(ri);
unwrap_reference_test<int const&, int const&>(ci);
unwrap_reference_test<int const&, int const&>(rci);
return 0;
}
普通引用測試
#include <boost/ref.hpp>
#include <boost/core/is_same.hpp>
#include <boost/static_assert.hpp>
#include <boost/detail/workaround.hpp>
namespace {
template< typename R, typename Ref >
void cxx_reference_test(Ref)
{
BOOST_STATIC_ASSERT((boost::core::is_same<R,Ref>::value));
}
} // namespace
int main()
{
int i = 0;
int& ri = i;
int const ci = 0;
int const& rci = ci;
// ordinary references/function template arguments deduction test
cxx_reference_test<int>(i);
cxx_reference_test<int>(ri);
cxx_reference_test<int>(ci);
cxx_reference_test<int>(rci);
cxx_reference_test<int&, int&>(i);
cxx_reference_test<int&, int&>(ri);
cxx_reference_test<int const&, int const&>(i);
cxx_reference_test<int const&, int const&>(ri);
cxx_reference_test<int const&, int const&>(ci);
cxx_reference_test<int const&, int const&>(rci);
return 0;
}
BOOST_TEST_REF及BOOST_TEST_CREF
#include <boost/ref.hpp>
#include <boost/core/lightweight_test.hpp>
#define BOOST_TEST_REF( x ) BOOST_TEST( &boost::ref( x ).get() == &x )
#define BOOST_TEST_CREF( x ) BOOST_TEST( &boost::cref( x ).get() == &x )
int main()
{
int x1 = 1;
int const x2 = 2;
int volatile x3 = 3;
int const volatile x4 = 4;
BOOST_TEST_REF( x1 );
BOOST_TEST_CREF( x1 );
BOOST_TEST_REF( x2 );
BOOST_TEST_CREF( x2 );
BOOST_TEST_REF( x3 );
BOOST_TEST_CREF( x3 );
BOOST_TEST_REF( x4 );
BOOST_TEST_CREF( x4 );
return boost::report_errors();
}
函式的引用及解引用
#include <boost/ref.hpp>
#include <boost/detail/lightweight_test.hpp>
void f0()
{
}
void f1(int)
{
}
void f2(int, int)
{
}
void f3(int, int, int)
{
}
void f4(int, int, int, int)
{
}
void f5(int, int, int, int, int)
{
}
void f6(int, int, int, int, int, int)
{
}
void f7(int, int, int, int, int, int, int)
{
}
void f8(int, int, int, int, int, int, int, int)
{
}
void f9(int, int, int, int, int, int, int, int, int)
{
}
#define BOOST_TEST_REF( f ) BOOST_TEST( &boost::ref( f ).get() == &f )
int main()
{
int v = 0;
BOOST_TEST_REF( v );
BOOST_TEST_REF( f0 );
BOOST_TEST_REF( f1 );
BOOST_TEST_REF( f2 );
BOOST_TEST_REF( f3 );
BOOST_TEST_REF( f4 );
BOOST_TEST_REF( f5 );
BOOST_TEST_REF( f6 );
BOOST_TEST_REF( f7 );
BOOST_TEST_REF( f8 );
BOOST_TEST_REF( f9 );
return boost::report_errors();
}
基本資料型別不支援自動引用及const 引用
}
void f1( boost::reference_wrapper< int const > )
{
}
int main()
{
f( 1 ); // should fail
f1( 1 ); // should fail
}
包裝引用類get函式
#include <boost/ref.hpp>
#include <boost/core/lightweight_test.hpp>
template<class T> void test( T const & t )
{
{
boost::reference_wrapper< T const > r = boost::ref( t );
BOOST_TEST_EQ( &r.get(), &t );
}
{
boost::reference_wrapper< T const > r = boost::cref( t );
BOOST_TEST_EQ( &r.get(), &t );
}
}
template<class T> void test_nonconst( T & t )
{
{
boost::reference_wrapper< T > r = boost::ref( t );
BOOST_TEST_EQ( &r.get(), &t );
}
{
boost::reference_wrapper< T const > r = boost::cref( t );
BOOST_TEST_EQ( &r.get(), &t );
}
}
int main()
{
int x = 0;
test( x );
test( boost::ref( x ) );
test( boost::cref( x ) );
test_nonconst( x );
{
boost::reference_wrapper< int > r = boost::ref( x );
test_nonconst( r );
}
{
boost::reference_wrapper< int const > r = boost::cref( x );
test_nonconst( r );
}
return boost::report_errors();
}
原始碼
namespace boost
{
#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, == 1600 )
struct ref_workaround_tag {};
#endif
// reference_wrapper
/**
@brief Contains a reference to an object of type `T`.
`reference_wrapper` is primarily used to "feed" references to
function templates (algorithms) that take their parameter by
value. It provides an implicit conversion to `T&`, which
usually allows the function templates to work on references
unmodified.
*/
template<class T> class reference_wrapper
{
public:
/**
Type `T`.
*/
typedef T type;
/**
Constructs a `reference_wrapper` object that stores a
reference to `t`.
@remark Does not throw.
*/
BOOST_FORCEINLINE explicit reference_wrapper(T& t): t_(boost::addressof(t)) {}
#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, == 1600 )
BOOST_FORCEINLINE explicit reference_wrapper( T & t, ref_workaround_tag ): t_( boost::addressof( t ) ) {}
#endif
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
/**
@remark Construction from a temporary object is disabled.
*/
BOOST_DELETED_FUNCTION(reference_wrapper(T&& t))
public:
#endif
/**
@return The stored reference.
@remark Does not throw.
*/
BOOST_FORCEINLINE operator T& () const { return *t_; }
/**
@return The stored reference.
@remark Does not throw.
*/
BOOST_FORCEINLINE T& get() const { return *t_; }
/**
@return A pointer to the object referenced by the stored
reference.
@remark Does not throw.
*/
BOOST_FORCEINLINE T* get_pointer() const { return t_; }
private:
T* t_;
};
// ref
/**
@cond
*/
#if defined( __BORLANDC__ ) && BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT(0x581) )
# define BOOST_REF_CONST
#else
# define BOOST_REF_CONST const
#endif
/**
@endcond
*/
/**
@return `reference_wrapper<T>(t)`
@remark Does not throw.
*/
template<class T> BOOST_FORCEINLINE reference_wrapper<T> BOOST_REF_CONST ref( T & t )
{
#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, == 1600 )
return reference_wrapper<T>( t, ref_workaround_tag() );
#else
return reference_wrapper<T>( t );
#endif
}
// cref
/**
@return `reference_wrapper<T const>(t)`
@remark Does not throw.
*/
template<class T> BOOST_FORCEINLINE reference_wrapper<T const> BOOST_REF_CONST cref( T const & t )
{
return reference_wrapper<T const>(t);
}
#undef BOOST_REF_CONST
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
/**
@cond
*/
#if defined(BOOST_NO_CXX11_DELETED_FUNCTIONS)
# define BOOST_REF_DELETE
#else
# define BOOST_REF_DELETE = delete
#endif
/**
@endcond
*/
/**
@remark Construction from a temporary object is disabled.
*/
template<class T> void ref(T const&&) BOOST_REF_DELETE;
/**
@remark Construction from a temporary object is disabled.
*/
template<class T> void cref(T const&&) BOOST_REF_DELETE;
#undef BOOST_REF_DELETE
#endif
// is_reference_wrapper
/**
@brief Determine if a type `T` is an instantiation of
`reference_wrapper`.
The value static constant will be true if the type `T` is a
specialization of `reference_wrapper`.
*/
template<typename T> struct is_reference_wrapper
{
BOOST_STATIC_CONSTANT( bool, value = false );
};
/**
@cond
*/
template<typename T> struct is_reference_wrapper< reference_wrapper<T> >
{
BOOST_STATIC_CONSTANT( bool, value = true );
};
#if !defined(BOOST_NO_CV_SPECIALIZATIONS)
template<typename T> struct is_reference_wrapper< reference_wrapper<T> const >
{
BOOST_STATIC_CONSTANT( bool, value = true );
};
template<typename T> struct is_reference_wrapper< reference_wrapper<T> volatile >
{
BOOST_STATIC_CONSTANT( bool, value = true );
};
template<typename T> struct is_reference_wrapper< reference_wrapper<T> const volatile >
{
BOOST_STATIC_CONSTANT( bool, value = true );
};
#endif // !defined(BOOST_NO_CV_SPECIALIZATIONS)
/**
@endcond
*/
// unwrap_reference
/**
@brief Find the type in a `reference_wrapper`.
The `typedef` type is `T::type` if `T` is a
`reference_wrapper`, `T` otherwise.
*/
template<typename T> struct unwrap_reference
{
typedef T type;
};
/**
@cond
*/
template<typename T> struct unwrap_reference< reference_wrapper<T> >
{
typedef T type;
};
#if !defined(BOOST_NO_CV_SPECIALIZATIONS)
template<typename T> struct unwrap_reference< reference_wrapper<T> const >
{
typedef T type;
};
template<typename T> struct unwrap_reference< reference_wrapper<T> volatile >
{
typedef T type;
};
template<typename T> struct unwrap_reference< reference_wrapper<T> const volatile >
{
typedef T type;
};
#endif // !defined(BOOST_NO_CV_SPECIALIZATIONS)
/**
@endcond
*/
// unwrap_ref
/**
@return `unwrap_reference<T>::type&(t)`
@remark Does not throw.
*/
template<class T> BOOST_FORCEINLINE typename unwrap_reference<T>::type& unwrap_ref( T & t )
{
return t;
}
// get_pointer
/**
@cond
*/
template<class T> BOOST_FORCEINLINE T* get_pointer( reference_wrapper<T> const & r )
{
return r.get_pointer();
}
/**
@endcond
*/
} // namespace boost