Załóżmy, że mam typ na żądanie:
struct mutable_callable
{
int my_mutable = 0;
int operator()() { // Not const
return my_mutable++;
}
};
Zauważ, że mutable_callable
ma non-const, operator()
która modyfikuje zmienną składową .....
Załóżmy teraz, że utworzyłem std::function
z mojego typu:
std::function<int()> foo = mutable_callable{};
Teraz mogę to zrobić:
void invoke(std::function<int()> const& z)
{
z();
}
int main()
{
invoke(foo); // foo changed.....oops
}
Teraz, o ile mogę powiedzieć, std::function
s operator()
jest const
według:
https://en.cppreference.com/w/cpp/utility/functional/function/operator ()
Więc mam przeczucie, że nie powinieneś być w stanie tego zrobić .....
Ale potem patrząc na: https://en.cppreference.com/w/cpp/utility/functional/function/function
To nie wydaje się ograniczać, czy typ wywoływalny ma stałą operator()
......
Moje pytanie brzmi więc: mam rację, zakładając, że std::function<int()> const&
jest to w zasadzie to samo, std::function<int()>&
że nie ma żadnej różnicy między zachowaniem tych dwóch ...... a jeśli tak, to dlaczego nie jest const
poprawne?
źródło
std::function
ma odpowiednikstruct a{ std::any x; };
w nim .....std::function
implementacji MSVC : i.stack.imgur.com/eNenN.png gdzieusing _Ptrt = _Func_base<_Ret, _Types...>
. Opieram swoją sprawę.Odpowiedzi:
To sprowadza się do tego samego, jak
struct A { int* x; };
, gdzie w sposóbconst A a;
można zmodyfikować wartość z*(a.x)
(ale nie tam, gdzie to wskazuje). Istnieje poziom pośrednictwa wstd::function
(od typu wymazywania), przez któryconst
nie jest propagowany.I nie,
std::function<int()> const& f
nie jest bez sensu. W przypadkustd::function<int()>& f
możesz przypisać inny funktorf
, czego nie można zrobić w tymconst
przypadku.źródło
std::vector
robi to,std::unique_ptr
nie robi. Wydaje mi się, żestd::function
tak naprawdę nie chodzi o wyrażanie niezmienników stanu funktora. Może moglibyśmy zmienić przeznaczenie obrzydliwych typów funkcji (tj.std::function<int() const>
) W celu rozróżnienia?unique_ptr
nie powinien propagować stałości, tak jak zwykły wskaźnik. Istd::function<int() const>
nie chciałbym się skompilować.std::function
powinna należeć do mnie nie jest jasne. Istd::function<int() const>
był hipotetyczny - oczywiście, że teraz się nie kompiluje, ale czy spełniłby on np. OP tutaj, gdyby można go było uznać za ważny, wyrażając „można przypisać funktory tylko zoperator() const
(lub bezpaństwowcami)”? (nawet jeśli za kulisami byłoby to dość okropne, ze względu na stosowanie ohydnych typów funkcji)?