D
darylew
I'm starting out on Visual Studio 2013 Express on my Windows 8.1 Pro laptop
(upgraded from Windows 8 Pro and Vista). My code:
//=====
template < std::size_t I, typename T, std::size_t ...N >
inline BOOST_CONSTEXPR
auto get( array_md<T, N...> const &a ) BOOST_NOEXCEPT -> T const &
{
static_assert( I < array_md<T, N...>::static_size, "Index too large" );
return a.data()[ I ];
}
template < std::size_t I, typename T, std::size_t ...N >
inline
auto get( array_md<T, N...> &a ) BOOST_NOEXCEPT -> T &
{ return const_cast<T &>( get<I>(const_cast<array_md<T,N...> const &>( a ))); }
template < std::size_t I, typename T, std::size_t ...N >
inline
auto get( array_md<T, N...> &&a ) BOOST_NOEXCEPT -> T &&
{ return std::forward<T>( get<I>(a) ); }
//=====
The third overload gives me the following error:
//=====
1>------ Build started: Project: ArrayMD, Configuration: Debug Win32 ------
1> arraymd_test.cpp
1>c:\users\daryle\documents\github\arraymd\include\boost\container\array_md..hpp(1868): error C2440: 'return' : cannot convert from 'char [6]' to 'char(&&)[6]'
1> You cannot bind an lvalue to an rvalue reference
1> c:\users\daryle\documents\github\arraymd\test\arraymd_test.cpp(1179) : see reference to function template instantiation 'T (&&boost::container::get<0,char[6],>(boost::container::array_md<char [6],> &&))' being compiled
1> with
1> [
1> T=char [6]
1> ]
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
//=====
I can't figure out a combination that makes VC++ like it. (Neither std::move or a direct static_cast<T&&> work.) Then I thought, "Does MS' implementation of tuple/pair/array's get skip the r-value overloads?". Checking it out, it does not (from <tuple>):
//=====
template<class _This,
class... _Rest>
struct tuple_element<0, tuple<_This, _Rest...> >
{ // select first element
typedef _This type;
typedef typename add_lvalue_reference<const _This>::type _Ctype;
typedef typename add_lvalue_reference<_This>::type _Rtype;
typedef typename add_rvalue_reference<_This>::type _RRtype;
typedef tuple<_This, _Rest...> _Ttype;
};
//...
template<size_t _Index,
class... _Types> inline
typename tuple_element<_Index, tuple<_Types...> >::_RRtype
get(tuple<_Types...>&& _Tuple)
{ // get rvalue reference to _Index element of tuple
typedef typename tuple_element<_Index, tuple<_Types...> >::_Ttype
_Ttype;
typedef typename tuple_element<_Index, tuple<_Types...> >::_RRtype
_RRtype;
return (_STD forward<_RRtype>(((_Ttype&)_Tuple)._Myfirst._Val));
}
//=====
I can't figure out how to adapt this. Help.
Daryle W.
(upgraded from Windows 8 Pro and Vista). My code:
//=====
template < std::size_t I, typename T, std::size_t ...N >
inline BOOST_CONSTEXPR
auto get( array_md<T, N...> const &a ) BOOST_NOEXCEPT -> T const &
{
static_assert( I < array_md<T, N...>::static_size, "Index too large" );
return a.data()[ I ];
}
template < std::size_t I, typename T, std::size_t ...N >
inline
auto get( array_md<T, N...> &a ) BOOST_NOEXCEPT -> T &
{ return const_cast<T &>( get<I>(const_cast<array_md<T,N...> const &>( a ))); }
template < std::size_t I, typename T, std::size_t ...N >
inline
auto get( array_md<T, N...> &&a ) BOOST_NOEXCEPT -> T &&
{ return std::forward<T>( get<I>(a) ); }
//=====
The third overload gives me the following error:
//=====
1>------ Build started: Project: ArrayMD, Configuration: Debug Win32 ------
1> arraymd_test.cpp
1>c:\users\daryle\documents\github\arraymd\include\boost\container\array_md..hpp(1868): error C2440: 'return' : cannot convert from 'char [6]' to 'char(&&)[6]'
1> You cannot bind an lvalue to an rvalue reference
1> c:\users\daryle\documents\github\arraymd\test\arraymd_test.cpp(1179) : see reference to function template instantiation 'T (&&boost::container::get<0,char[6],>(boost::container::array_md<char [6],> &&))' being compiled
1> with
1> [
1> T=char [6]
1> ]
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
//=====
I can't figure out a combination that makes VC++ like it. (Neither std::move or a direct static_cast<T&&> work.) Then I thought, "Does MS' implementation of tuple/pair/array's get skip the r-value overloads?". Checking it out, it does not (from <tuple>):
//=====
template<class _This,
class... _Rest>
struct tuple_element<0, tuple<_This, _Rest...> >
{ // select first element
typedef _This type;
typedef typename add_lvalue_reference<const _This>::type _Ctype;
typedef typename add_lvalue_reference<_This>::type _Rtype;
typedef typename add_rvalue_reference<_This>::type _RRtype;
typedef tuple<_This, _Rest...> _Ttype;
};
//...
template<size_t _Index,
class... _Types> inline
typename tuple_element<_Index, tuple<_Types...> >::_RRtype
get(tuple<_Types...>&& _Tuple)
{ // get rvalue reference to _Index element of tuple
typedef typename tuple_element<_Index, tuple<_Types...> >::_Ttype
_Ttype;
typedef typename tuple_element<_Index, tuple<_Types...> >::_RRtype
_RRtype;
return (_STD forward<_RRtype>(((_Ttype&)_Tuple)._Myfirst._Val));
}
//=====
I can't figure out how to adapt this. Help.
Daryle W.