5

constの正当性に関する簡単な質問があります。

私はこのクラスを持っています:

template <class T>
class Foo
{
public:
    std::map<std::string, boost::any> members; 

    template <typename T>
    std::vector<T>& member(const std::string& memberName) 
    {
        return boost::any_cast<std::vector<T>&>(members[memberName]);
    }
};

次に、次の機能を含むファンクターがあります。

bool operator()(Foo& foo) const
{
    std::vector<T> & member = foo.member<T>(_memberName);

ここで私を混乱させているのは、非constメンバーのgetter関数を呼び出しているため、constを参照してFooを渡すことができないことです。その署名に関して、これはoperator()がfooを変更するという印象を与えます。

これを修正する必要がありますか?修正する場合はどうすればよいですか?

4

2 に答える 2

9

通常の方法はconst、メンバー関数にオーバーロードを追加することです。

template <typename T>
std::vector<T> const & member(const std::string& memberName) const
{              ^^^^^                                         ^^^^^
    return boost::any_cast<std::vector<T> const &>(members.at(memberName));
}                                         ^^^^^            ^^

でメンバーを呼び出すと、const Fooこのオーバーロードが選択されます。非でそれを呼び出すとconst 、元のものが選択されます。

at()これは、へのかなり新しい追加であることに注意してくださいstd::map。古いライブラリで立ち往生している場合は、次のようなものが必要になります。

std::map<std::string, boost::any>::const_iterator found = members.find(memberName);
if (found == members.end()) {
    throw std::runtime_error("Couldn't find " + memberName);
}
return boost::any_cast<std::vector<T> const &>(found->second);
于 2012-09-14T14:09:50.770 に答える
2

constの正当性は、メソッドを実行するオブジェクトに適用されます。それで:

bool operator()(Foo& foo) const

これは、(ファンクタークラスのメンバーのようですoperator())のように、ファンクタークラスでは何も変更されないことを意味します。_memberName

それが定義されている方法では、Fooを変更することができます(非constメソッドを呼び出す)。

編集:それを修正する方法を説明しているので、マイク・シーモアの答えを参照してください。私は個人的にそれをたくさんしましたが、あなたの質問を正確に得られなかったようです。:)

于 2012-09-14T14:11:02.563 に答える