Adding a const qualifier to a member function

I am currently writing an interface class that should provide access to internal elements of complex structure as constant or non-constant links. The idea is that some modules are granted access to const, and some modules are granted full access.

I used 'type_traits' 'std :: add_const' to conditionally qualify the return type of internal member functions, unfortunately I cannot think of a way to conditionally define member functions as const or non-const.

Is it possible? if so, how?

eg:

template< typename T, bool isConst  >
struct apply_const
{
    typedef T type;
};

template<typename T>
struct apply_const<T, true>
{
    typedef typename std::add_const<T>::type type;
};

template< bool isConst >
const Interface
{
    /// @brief get the TypeA member
    typename apply_const<TypeA, isConst >::type& GetXpo3Container()  // how do I conditionally add a const qualifier
    {
        return config_.type_a_member_;
    }

    typename apply_const<Profile, isConst >::type& GetProfile( unint32_t id )  // qualifier ???
    {
        return config_.profiles.get( id );
    }

    // .... lots more access functions

    ConfigType config_; // the config
};

. / 2- , config - , , - . Netconf, <running> <candidate>.

+3
3

:

template< bool isConst >
struct Interface;

template <>
struct Interface<false>
{
    TypeA& GetXpo3Container()
    {
        return config_.type_a_member_;
    }
};

template <>
struct Interface<true>
{
    const TypeA& GetXpo3Container() const
    {
        return config_.type_a_member_;
    }
};

: , .

struct Interface
{
    TypeA::type& GetXpo3Container()
    {
        return config_.type_a_member_;
    }
    const TypeA::type& GetXpo3Container() const
    {
        return config_.type_a_member_;
    }
};

const Interface, ? ?

2: std::enable_if , .

+5

, isConst , - const, const .

- ( const ) enable_if, .

+1

SFINAE:

template<bool isConst>
struct Interface
{
    template<
        bool Cond = isConst
        , typename std::enable_if<!Cond, int>::type = 0            
    >
    TypeA&
    GetXpo3Container() const
    {
        return config_.type_a_member_;
    }

    template<
        bool Cond = isConst
        , typename std::enable_if<Cond, int>::type = 0
    >
    TypeA const&
    GetXpo3Container() const
    {
        return config_.type_a_member_;
    }
};

, , typename std::enable_if<Cond, int>::type - std::enable_if<isConst, int>::type , , -error, , SFINAE.

However, the default setting means that someone can do this, for example. Interface<true> f; TypeA& ref = f.GetXpo3Container<false>();. If you want to avoid this (for example, you do not trust users to not abuse the unspecified bits of your interface), here is another way to make the dependent element typeof std::enable_ifmore suitable, but somewhat more mysterious:

template<typename T, T Value, typename>
struct depend_on_c {
    static constexpr T value = Value;
};

/* and in the scope of Interface: */
    template<
        typename Dummy = void
        , typename std::enable_if<
            depend_on_c<bool, isConst, Dummy>::value
            , int
         >::type = 0
    >
    /* rest as before */
+1
source

All Articles