Tenho duas versões da mesma função usando std::any_of
e std::find_if
para verificar se int
existe em um vetor (retornado de g.getEdges()
).
Entretanto, quando executo repetidamente o std::any_of
valor de retorno é inconsistente, enquanto std::find_if
é.
Ambas as versões são as seguintes ( g.getEdges()
retorna um int
vetor, enquanto this->s
é um int
):
bool Search::marked(const int &v) {
return std::any_of(begin(g.getEdges(v)), end(g.getEdges(v)), [this](const int &w) { return w == this->s; });
}
bool Search::marked(const int &v) {
auto it = std::find_if(begin(g.getEdges(v)), end(g.getEdges(v)), [this](const auto &w) { return w == this->s; });
return it != end(g.getEdges(v));
}
Em ambas as classes, adj
o vetor está sendo iterado:
class Graph {
public:
Graph() : vertex(0), edges(0) {
adj = std::make_unique<std::vector<std::vector<int>>>(0);
}
const std::vector<int> getEdges(int v) { return (*adj)[v]; }
// ... rest of public
private:
std::shared_ptr<std::vector<std::vector<int>>> adj; // Shared for Search class
}
class Search {
public:
Search(Graph &g_, int s_) : g(g_), s(s_) {}
int count();
bool marked(const int &v);
private:
Graph &g;
int s;
};
A função gtest que usei para verificar o código:
TEST(searchClassTest, HandlesPositiveInput) {
// ... init myGraph ...
Search mySearch(myGraph, 2); // 2 is s!
EXPECT_EQ(mySearch.count(), 2);
EXPECT_EQ(mySearch.marked(1), true);
EXPECT_EQ(mySearch.marked(3), true);
}
Por que estou obtendo resultados inconsistentes?
Link para o exemplo mínimo reproduzível: https://godbolt.org/z/9TnGq3Wbs
O código que você apresentou é totalmente inválido devido a
Em ambas as implementações de
marked
, você chama essa função várias vezes, cada vez obtendo uma cópia diferente de um vetor, e então tenta comparar seus iteradores:A
std::any_of
versão está quebrada da mesma forma. Tentar iterar de um vetor para outro é um comportamento indefinido, então qualquer resultado que você veja pode ser aleatório - a função pode retornartrue
,false
,7
ou"nasal demons, here I come"
.Simplesmente alterar
getEdges
para retornar uma referência deve corrigir isso.