Opened 11 years ago

Closed 4 years ago

#5795 closed Bugs (duplicate)

is_rvalue_reference returns wrong result when rvalue reference to a function is passed

Reported by: sscrisk@… Owned by: John Maddock
Milestone: To Be Determined Component: type_traits
Version: Boost 1.47.0 Severity: Problem
Keywords: Cc:

Description

On Visual C++ 10.0.

Compile error occured:

#include <boost/type_traits/is_rvalue_reference.hpp>

static_assert(boost::is_rvalue_reference<void (&&)()>::value == true, "");

int main(){}

info: Compile error occured use std::is_rvalue_reference

Change History (4)

comment:1 by anonymous, 11 years ago

I don't see an easy fix for this - it looks like a compiler bug - and std::is_rvalue_reference is implemented in exactly the same way as our trait, and has the same issue :-(

BTW we do have a test case for this (tricky_rvalue_test.cpp), and the issue has been reported to the VC++ team.

comment:2 by iorate <iorate_stage@…>, 11 years ago

Partial specilizations help solve the problem.

For example, the following additional header works well.

is_rvalue_reference_patch.hpp (please place this file in the include paths)

#ifndef BOOST_PP_IS_ITERATING


    #ifndef IS_RVALUE_REFERENCE_PATCH_HPP
    #define IS_RVALUE_REFERENCE_PATCH_HPP


    #include <boost/mpl/bool.hpp>
    #include <boost/preprocessor/iteration/iterate.hpp>
    #include <boost/preprocessor/punctuation/comma_if.hpp>
    #include <boost/preprocessor/repetition/enum_params.hpp>
    #include <boost/preprocessor/repetition/enum_trailing_params.hpp>
    #include <boost/type_traits/is_rvalue_reference.hpp>


    namespace boost {


        #define BOOST_PP_ITERATION_PARAMS_1 (3, (0, 25, "is_rvalue_reference_patch.hpp"))
        #include BOOST_PP_ITERATE()


    } // namespace boost


    #endif // IS_RVALUE_REFERENCE_PATCH_HPP


#else


    #define n BOOST_PP_ITERATION()


        template <class R BOOST_PP_ENUM_TRAILING_PARAMS(n, class A)>
        struct is_rvalue_reference<R (&&)(BOOST_PP_ENUM_PARAMS(n, A))>
          : boost::mpl::true_
        {};

        template <class R BOOST_PP_ENUM_TRAILING_PARAMS(n, class A)>
        struct is_rvalue_reference<R (&&)(BOOST_PP_ENUM_PARAMS(n, A) BOOST_PP_COMMA_IF(n) ...)>
          : boost::mpl::true_
        {};


    #undef n


#endif

test.cpp

#include <boost/static_assert.hpp>
#include <boost/type_traits/is_rvalue_reference.hpp>
#include "./is_rvalue_reference_patch.hpp"


BOOST_STATIC_ASSERT((boost::is_rvalue_reference<int (&&)(int)>::value));
BOOST_STATIC_ASSERT((boost::is_rvalue_reference<int (&&)(int, ...)>::value));

comment:4 by John Maddock, 4 years ago

Resolution: duplicate
Status: newclosed
Note: See TracTickets for help on using tickets.