How do I remove code duplication between similar const and non-const member functions?

后端 未结 19 1707
天涯浪人
天涯浪人 2020-11-22 00:30

Let\'s say I have the following class X where I want to return access to an internal member:

class Z
{
    // details
};

class X
{
    std::vec         


        
相关标签:
19条回答
  • 2020-11-22 01:19

    I think Scott Meyers' solution can be improved in C++11 by using a tempate helper function. This makes the intent much more obvious and can be reused for many other getters.

    template <typename T>
    struct NonConst {typedef T type;};
    template <typename T>
    struct NonConst<T const> {typedef T type;}; //by value
    template <typename T>
    struct NonConst<T const&> {typedef T& type;}; //by reference
    template <typename T>
    struct NonConst<T const*> {typedef T* type;}; //by pointer
    template <typename T>
    struct NonConst<T const&&> {typedef T&& type;}; //by rvalue-reference
    
    template<typename TConstReturn, class TObj, typename... TArgs>
    typename NonConst<TConstReturn>::type likeConstVersion(
       TObj const* obj,
       TConstReturn (TObj::* memFun)(TArgs...) const,
       TArgs&&... args) {
          return const_cast<typename NonConst<TConstReturn>::type>(
             (obj->*memFun)(std::forward<TArgs>(args)...));
    }
    

    This helper function can be used the following way.

    struct T {
       int arr[100];
    
       int const& getElement(size_t i) const{
          return arr[i];
       }
    
       int& getElement(size_t i) {
          return likeConstVersion(this, &T::getElement, i);
       }
    };
    

    The first argument is always the this-pointer. The second is the pointer to the member function to call. After that an arbitrary amount of additional arguments can be passed so that they can be forwarded to the function. This needs C++11 because of the variadic templates.

    0 讨论(0)
提交回复
热议问题