完全に個人的なメモなので気にしないよ〜に.
#include <iostream> #include <boost/mpl/identity.hpp> #include <boost/mpl/if.hpp> #include <boost/type_traits/is_volatile.hpp> #include <boost/static_assert.hpp> struct volatile_refused; template< class T, class R = void > struct refuse_volatile : public boost::mpl::if_< boost::is_volatile< T > , volatile_refused , boost::mpl::identity< R > >::type {}; template< class T > typename refuse_volatile< T, void >::type discriminate( T & ) { std::cout << "L" << std::endl; } template< class T > void discriminate( T const volatile & ) { // If you want to get nonvolatile `T', use `const_cast< T const & >' here. // Such `const_cast' is completely legal. std::cout << "R" << std::endl; } int return_rvalue() { return 0; } int const return_const_rvalue() { return 0; } int main() { int i = 0; discriminate( i ); // -> "L". int const ci = 0; discriminate( ci ); // -> "L". discriminate( 0 ); // -> "R". discriminate( return_rvalue() ); // -> "R". discriminate( return_const_rvalue() ); // -> False "L". // This is the only remaining // problem. In the current standard, // this may be unsolvable (If it // were resolved, it would be an // rvalue reference emulation). int volatile vi = 0; //discriminate( vi ); // Triggers an expected compile error. int const volatile cvi = 0; //discriminate( cvi ); // Triggers an expceted compile error. }
#あ,違うわ.右辺値識別は(ほぼ)解けているけれど the Perfect Forwarding にはなってないや.