std :: function const correctness


11

次のような呼び出し可能なタイプがあるとします。

struct mutable_callable
{
    int my_mutable = 0;
    int operator()() { // Not const
        return my_mutable++;
    }
};

メンバー変数を変更するmutable_callable非定数があることに注意してくださいoperator().....

ここstd::functionで、自分のタイプからout を作成するとします。

std::function<int()> foo = mutable_callable{};

今私はこれを行うことができます:

void invoke(std::function<int()> const& z)
{
    z();
}

int main()
{
    invoke(foo); // foo changed.....oops
}

今、私の知る限りstd::functionsがoperator()あるconstごとに: https://en.cppreference.com/w/cpp/utility/functional/function/operator()

だから、私の直感は、あなたがこれを行うことができないはずだということです...

しかし、次に見て:https : //en.cppreference.com/w/cpp/utility/functional/function/function

これは、呼び出し可能な型に定数があるかどうかに制約を課していないようですoperator()......

だから私の質問はこれです:それstd::function<int()> const&は本質的にそれと同じものであると仮定するのは正しいですstd::function<int()>&が、実際には2つの動作に違いはありません......そしてそれが事実である場合、なぜそれがconst正しくないのですか?


@MaxLanghof No ..... std::functionはそれに相当するstruct a{ std::any x; };.....
DarthRubik

以下は、MSVC std::function実装の内部の小さなスニペットです。i.stack.imgur.com / eNenN.pngここでusing _Ptrt = _Func_base<_Ret, _Types...>。私はケースを休ませる。
Max Langhof

回答:


3

これは同じに帰着するstruct A { int* x; };ところでは、const A a;あなたが変更することができますのを*(a.x)(それが指していない場合)。伝播されないstd::function(タイプ消去からの)間接参照のレベルがありconstます。

いいえ、std::function<int()> const& f無意味ではありません。では、std::function<int()>& f別のファンクタをに割り当てることができfますが、この場合はできませんconst


うん.....それは実際に多くの意味をなす.....しかし、一見するとまだ混乱しています
DarthRubik

それは設計上の欠陥だと思います。この間接化は、ユーザーに対して透過的な実装の詳細である必要があり、一定のメタプログラミングを使用して不変性を伝播できます。
Igor R.

@IgorR。はい、誠実さが広まる可能性があります。std::vectorこれを行いstd::unique_ptrません。でもstd::function、ファンクターの状態の不変式を表現することについては、私は本当に感じていません。多分私達はstd::function<int() const>区別するために忌まわしくない関数の型(すなわち)を転用することができるでしょうか?
Max Langhof

unique_ptr通常のポインタが伝搬しないように、constnessを伝搬すべきではありません。そしてstd::function<int() const>、コンパイルしません。
Igor R.

@IgorR。知っている。私の要点は、標準ライブラリの一部はそれを実行し、一部は実行しないということでした。どのカテゴリに分類std::functionすべきかは、私にはわかりません。そして、これstd::function<int() const>は仮説でした-もちろん今はコンパイルされませんが、たとえば、OPが有効になり、「operator() const(またはステートレスな)ファンクタのみを割り当てることができる」と表現できれば、ここのOPを満たすでしょうか?(たとえひどい目に見えても、忌まわしくない関数タイプを使用しているため)
Max Langhof
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.