2013-08-16 7 views
5

Mam funkcji szablonu:Co jest nie tak z odrzutami typu ulotnego w funkcjach szablonu?

template <typename T> 
inline void Acquire_Store(volatile T* ptr, T value) { 
    // ... 
} 

Kiedy próbuję wywołać ją tak:

volatile Node* node; 
Acquire_Store(&node, static_cast<Node*>(nullptr)); 

obu g ++, dzyń ++ kompilatory powiedzieć coś takiego:

wywnioskować sprzeczne typy dla parametru 'T' ('lotny Lista :: Node *' vs. 'Lista :: Node *')

Co to jest poprawny sposób, aby wywołać tę funkcję szablonu?

Aktualizacja.

Teraz nie jestem pewien typ node „s - Może powinienem go zmienić na Node* volatile node;?

Chcę zmienna node być niestabilne, ale nie spiczasty przedmiot.

+2

@ abyss.7 wykonując 'static_cast' zmuszasz kompilator do myślenia, że' T' to dwa różne typy w tym samym czasie :) - prawdopodobnie będzie to możliwe na komputerach kwantowych z 2113 roku, ale nie obecnie :) – zaufi

+0

@zaufi może 'static_cast' to jest zła rzecz - ale nie wiem, jak wykonać prawidłowe połączenie - o to właśnie chodzi. –

+0

czego dokładnie chcesz? oczywiście musisz zmienić sygnaturę lub stronę połączenia. – zaufi

Odpowiedz

1

Podstawienie i dedukcja nie jest leksykalna jak w przypadku makra. volatile T* nie stanie się volatile Node**, ale volatile Node* volatile*. Druga zmienna pochodzi z szablonu. To sprawia, że ​​T jest równy volatile Node* dla pierwszego parametru.

Postaraj się uwolnić od trzymania lotności zawsze na początku, ale umieść ją zgodnie z aktualnym typem. Lotny wskaźnik ma lotność po gwiazdce, a nie przed nią.

0

Kompilator faktycznie powiedział o swoim problemie wystarczająco wyraźnie: nie można mieć różnych typów w tym samym czasie (instancji). to dlatego, że drugi parametr został nieprawidłowo rzucony. na przykład można „naprawić” to tak:

// kate: hl C++11; 
#include <iostream> 

struct Node {}; 

template <typename T> 
inline void Acquire_Store(volatile T* ptr, T value) 
{ 
    std::cout << __PRETTY_FUNCTION__ << std::endl; 
} 

int main() 
{ 
    volatile Node* node; 
    Acquire_Store(&node, static_cast<volatile Node*>(nullptr)); 
    return 0; 
} 

wtedy wyjście będzie

void Acquire_Store(volatile T*, T) [with T = volatile Node*] 

ale ja nadal nie rozumiem, co chcesz przez to osiągnąć ...

+0

Zaktualizowałem pytanie. Być może, uzyskasz lepsze zrozumienie. –

0

Wydaje się, że problem polega na tym, że kwalifikator volatile jest powiązany z dowolnym typem T.

template <typename T> 
inline void Acquire_Store(volatile T* ptr, T value) 

Więc kiedy T = Node * dla powyższego, jest to wskaźnik do węzła że jest lotna i nie samego węzła. Aby wskazać obiektowi lotne kwalifikacje, musi on być częścią T. Jest to problem, ponieważ twój drugi parametr jest nielotny - T nie może jednocześnie być niestabilny i nielotny.

Co można zrobić, to T = volatile Node * a następnie usunąć ten lotny kwalifikator z drugiego argumentu używając type_traits:

template <typename T> 
inline void Acquire_Store(T *ptr, typename std::remove_volatile<T>::type value); 

Uwaga ta dotyczy wszystkich do const kwalifikatora, jak również. Ideone demos this for const qualifier.