Supposons que j'ai un type appelable comme ceci:
struct mutable_callable
{
int my_mutable = 0;
int operator()() { // Not const
return my_mutable++;
}
};
Notez que mutable_callable
possède un non-const operator()
qui modifie une variable membre .....
Supposons maintenant que je crée un std::function
de mon type:
std::function<int()> foo = mutable_callable{};
Maintenant, je peux le faire:
void invoke(std::function<int()> const& z)
{
z();
}
int main()
{
invoke(foo); // foo changed.....oops
}
Maintenant , pour autant que je peux dire std::function
s operator()
est const
comme par:
https://en.cppreference.com/w/cpp/utility/functional/function/operator ()
Donc, mon instinct est que vous ne devriez pas pouvoir faire ça .....
Mais en regardant ensuite: https://en.cppreference.com/w/cpp/utility/functional/function/function
Cela ne semble pas imposer de contraintes quant au fait que le type appelable ait ou non une constante operator()
......
Donc ma question est la suivante: j'ai raison de supposer que std::function<int()> const&
c'est essentiellement la même chose que std::function<int()>&
c'est qu'il n'y a pas réellement de différence entre le comportement des deux ...... et si c'est le cas pourquoi n'est-ce pas const
correct?
la source
std::function
a l'équivalent d'un astruct a{ std::any x; };
dedans .....std::function
implémentation MSVC : i.stack.imgur.com/eNenN.png oùusing _Ptrt = _Func_base<_Ret, _Types...>
. Je me repose mon cas.Réponses:
Cela se résume à la même chose que
struct A { int* x; };
, où dans un,const A a;
vous pouvez modifier la valeur de*(a.x)
(mais pas où elle pointe). Il existe un niveau d'indirectionstd::function
(à partir de l'effacement de type) à travers lequelconst
ne se propage pas.Et non, ce
std::function<int()> const& f
n'est pas inutile. Dans un,std::function<int()>& f
vous seriez en mesure d'affecter un foncteur différentf
, ce que vous ne pouvez pas faire dans leconst
cas.la source
std::vector
fait cela,std::unique_ptr
non. Je pense qu'ilstd::function
ne s'agit pas vraiment d'exprimer des invariants de l'état du foncteur. Peut-être pourrions-nous réutiliser des types de fonctions abominables (c.std::function<int() const>
-à- d. ) Pour distinguer?unique_ptr
ne doit pas propager la constance, contrairement au pointeur normal. Etstd::function<int() const>
ne compilerait pas.std::function
à laquelle je dois entrer n'est pas claire pour moi. Etstd::function<int() const>
c'était une hypothèse - bien sûr, il ne compile pas maintenant, mais satisferait-il par exemple l'OP ici si cela pouvait être rendu valide, exprimant "ne peut être affecté que des foncteurs avec unoperator() const
(ou des apatrides)"? (même si en coulisses ce serait assez atroce, en raison de l'utilisation de types de fonctions abominables)?