Мне нужна прозрачная оболочка вокруг структуры данных, чтобы добавить некоторые свойства. Самый простой что-то вроде этого:Добавить const при доступе к переменной-члену
template<typename T>
struct Wrapper{
T values;
}
Теперь я хочу, чтобы передать это аксессор и держать константность. База будет:
template<class T>
T& accVal(usigned idx, T* vals){ return vals[idx]; }
template<class T>
const T& accVal(usigned idx, const T* vals){ return vals[idx]; }
template<class T>
auto
acc(unsigned idx, T& data) -> decltype(accVal(idx, data.values))
{
return accVal(idx, data.values);
}
//Example:
Wrapper<int*> intsWrapped;
cout << acc(1, intsWrapped);
Это работает только для не-указателей, скажем, заменить «T *» с структурой, как доступ к data.values отбрасывается константность данных, и я был бы в состоянии манипулировать она как :
void foo(const Wrapper<int*>& bar){ acc(1, bar) = 5; }
Это опасно в моем приложении.
Итак, как я могу сохранить постоянство? Я пытался что-то вроде этого:
template< class T_Base, typename T_Mem >
struct GetConstCorrect
{
template< typename T >
struct AddConstVal: std::add_const<T>{};
template< typename T >
struct AddConstVal<T&>
{
using type = std::add_const_t<T> &;
};
template< typename T >
struct AddConstVal<T*>
{
using type = std::add_const_t<T>*;
};
template< typename T >
struct AddConstVal<T* const>
{
using type = std::add_const_t<T>* const;
};
template< typename T >
struct AddConstVal<T*&>
{
using type = std::add_const_t<T>*&;
};
template< typename T >
struct AddConstVal<T*const &>
{
using type = std::add_const_t<T>* const &;
};
using Base = T_Base;
using Mem = T_Mem;
static constexpr bool isConst = std::is_const<Base>::value;
using type = std::conditional_t< isConst,
typename AddConstVal<Mem>::type,
Mem
>;
};
template< class T_Base, typename T_Mem >
using GetConstCorrect_t = typename GetConstCorrect< T_Base, T_Mem >::type;
template< class T_Base, typename T_Mem >
GetConstCorrect_t< T_Base, T_Mem& >
getConstCorrect(T_Mem& mem)
{
return const_cast<GetConstCorrect_t< T_Base, T_Mem& >>(mem);
}
И data.values доступа по getConstCorrect (data.values), но это по-прежнему кажется, подвержены ошибкам. (Например, мультипотоп, такой как int **, станет int const not int const **)
Есть ли лучший способ достичь этого?