2013-08-05 37 views
6

Zastanawiam się, czy istnieje sposób sprawdzenia, czy wskaźnik funkcji przypisany do std::function był nullptr. Spodziewałem się, że operator-! to zrobi, ale wydaje się, że działa tylko wtedy, gdy funkcja została przypisana coś typu nullptr_t.Sprawdzanie, czy funkcja std :: jest przypisana do nullptr

typedef int (* initModuleProc)(int); 

initModuleProc pProc = nullptr; 
std::function<int (int)> m_pInit; 

m_pInit = pProc; 
std::cout << !pProc << std::endl; // True 
std::cout << !m_pInit << std::endl; // False, even though it's clearly assigned a nullptr 
m_pInit = nullptr; 
std::cout << !m_pInit << std::endl; // True 

Napisałem tę funkcję pomocnika, aby obejść to na teraz.

template<typename T> 
void AssignToFunction(std::function<T> &func, T* value) 
{ 
    if (value == nullptr) 
    { 
     func = nullptr; 
    } 
    else 
    { 
     func = value; 
    } 
} 
+0

Masz na myśli "przypisany coś typu" nullptr_t "", prawda? Kiedy po raz pierwszy przeczytałem odpowiedzi, pomyślałem, że robisz rozróżnienie między inicjalizacją a przypisaniem, ale teraz widzę inaczej. –

+2

Należy unikać nieprzenośnych bzdur takich jak '__cdecl' i' HWND' w przykładach, twoje pytanie nie zależy od niczego specyficznego dla systemu Windows, więc nie ma powodu, aby nie używać typu funkcji, takiego jak 'void()', który może być testowane przez każdego na dowolnej platformie. –

+0

Usunąłem części specyficzne dla systemu Windows i zmienię je na "typ nullptr_t" –

Odpowiedz

8

To błąd w implementacji std::function (a także widocznie w kopalni), standard mówi, że operator! zwraca true, jeśli obiekt jest zbudowany z zerowym wskaźnikiem funkcji, patrz [func.wrap.func] Punkt 8. Operator przypisania powinien być równoważny do skonstruowania std::function z argumentem i zamianą go, więc operator! powinien również zwrócić wartość true w tym przypadku.

+0

Czy nie jest to 'jawny operator bool()'? – dyp

+1

@DyP: I '!' Powoduje konwersję kontekstową na wartość bool, która wywołuje operatora jawnego. –

+0

@DyP, miałem na myśli globalny 'operator!', Który jest używany w testcadzie, a nie 'std :: function :: operator! '(Który nie istnieje). –