Suponha que eu tenha um tipo de chamada assim:
struct mutable_callable
{
int my_mutable = 0;
int operator()() { // Not const
return my_mutable++;
}
};
Observe que mutable_callable
possui um não-const operator()
que modifica uma variável de membro .....
Agora, suponha que eu crie um std::function
fora do meu tipo:
std::function<int()> foo = mutable_callable{};
Agora eu posso fazer isso:
void invoke(std::function<int()> const& z)
{
z();
}
int main()
{
invoke(foo); // foo changed.....oops
}
Agora, tanto quanto eu posso dizer, std::function
s operator()
é o seguinte const
:
https://en.cppreference.com/w/cpp/utility/functional/function/operator ()
Então, meu pressentimento é que você não deve ser capaz de fazer isso ...
Mas, em seguida, consulte: https://en.cppreference.com/w/cpp/utility/functional/function/function
Isso não parece restringir se o tipo de chamada tem ou não uma constante operator()
......
Portanto, minha pergunta é a seguinte: estou certo ao supor que std::function<int()> const&
é essencialmente a mesma coisa std::function<int()>&
que não existe realmente diferença entre o comportamento dos dois ...... e, se for esse o caso, por que não está const
correto?
fonte
std::function
tem o equivalente a umstruct a{ std::any x; };
.....std::function
implementação do MSVC : i.stack.imgur.com/eNenN.png ondeusing _Ptrt = _Func_base<_Ret, _Types...>
. Eu descanso meu caso.Respostas:
Isso se resume ao mesmo que
struct A { int* x; };
, em queconst A a;
você pode modificar o valor de*(a.x)
(mas não para onde aponta). Existe um nível de indireçãostd::function
(a partir do tipo apagamento) pelo qualconst
não é propagado.E não,
std::function<int()> const& f
não é inútil. Em umstd::function<int()>& f
você seria capaz de atribuir um functor diferentef
, o que você não pode fazer noconst
caso.fonte
std::vector
faz isso,std::unique_ptr
não faz. eu sintostd::function
não é realmente sobre expressar invariantes do estado functor. Talvez pudéssemos redirecionar tipos de funções abomináveis (iestd::function<int() const>
) para distinguir?unique_ptr
não deve propagar constness, como o ponteiro regular não. Estd::function<int() const>
não compilaria.std::function
deve se encaixar não está clara para mim. E issostd::function<int() const>
era hipotético - é claro que não compila agora, mas seria satisfatório, por exemplo, o OP aqui se isso pudesse ser validado, expressando "só podem ser atribuídos atribuidores de função comoperator() const
(ou sem estado)"? (mesmo nos bastidores, isso seria bastante atroz, devido ao uso de tipos de funções abomináveis)?