5

現在、const または non-const 参照として複雑な構造の内部要素へのアクセスを提供するインターフェイス クラスを作成しています。一部のモジュールには const アクセスが許可され、一部のモジュールにはフル アクセスが許可されるという考え方です。

「type_traits」「std::add_const」を使用して、内部メンバー関数の戻り値の型を条件付きで修飾しましたが、残念ながら、メンバー関数を const または非 const として条件付きで修飾する方法は考えられません。

これは可能ですか?もしそうならどのように?

例えば:

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(書き込み可能なものとそうでないもの) へのアクセスを提供することです。開発中のサブシステムは<running><candidate>構成をサポートする組み込みの Netconf エージェントです。

4

3 に答える 3

2

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_;
    }
};

2 つのメンバーをテンプレートにする必要があり、デフォルトのパラメーターを使用して強制typename std::enable_if<Cond, int>::type的に依存させることに注意してください。クラスのスコープでは依存していないstd::enable_if<isConst, int>::typeため、クラスがインスタンス化されるとハード エラーが発生しますSFINAEが欲しい。

ただし、デフォルトのパラメーターは、誰かができることを意味しますInterface<true> f; TypeA& ref = f.GetXpo3Container<false>();。それを避けたい場合 (たとえば、ユーザーがインターフェイスの未指定部分を悪用しないとは信じていない場合)、依存関係のメンバーtypestd::enable_if再度作成する別の方法があります。これはおそらくより適切ですが、やや難解です:

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 */
于 2012-04-11T16:50:45.000 に答える
1

isConsttrueのケースに合わせてテンプレートを特殊化し、このケースではすべてのメンバー関数を作成し、プライマリ テンプレートにはconst非のままにすることができます。const

または、メンバー関数の 2 つのバージョン (1constつとそれ以外) を記述enable_ifし、適切なオーバーロードを有効にするためにのみ使用します。

于 2012-04-11T16:41:18.117 に答える