2010-03-11 20 views
11

mam ten kod:Visual Studio 2010 i std :: funkcja

#include <iostream> 
#include <functional> 

struct A 
{ 
    int operator()(int i) const { 
     std::cout << "F: " << i << std::endl; 
     return i + 1; 
    } 
}; 

int main() 
{ 
    A a; 
    std::tr1::function<int(int)> f = std::tr1::ref(a); 
    std::cout << f(6) << std::endl; 
} 

Celem jest przekazanie obiektu funktora przez reference_wrapper, w taki sposób, aby uniknąć niepotrzebnych połączeń kopia Costructor. Spodziewam się następujący wynik:

F: 6 
7 

działa poprawnie z GCC> = 4.4.0, Visual Studio 2008 i podbicia przez zastąpienie nazw std :: TR1 z doładowania. To nie działa z nowym Visual Studio 2010 zarówno Express Beta 2, jak i Release Candidate.

Czy te nowe funkcje C++ są podsłuchiwane w vs2010? Czy jest jakiś błąd lub nadużycie w kodzie?

+0

Jak to nie działa? – UncleBens

+0

@litb: Myślę, że OP ma problemy z używaniem klasy szablonów 'std :: tr1 :: ref' i * not * boost w VS2010. – dirkgently

+0

Oto wynik kompilacji VS2010: http://pastebin.com/YQf4Qe8W –

Odpowiedz

11

Myślę, że znalazłem przyczynę. To co TR1 3.4/2 mówi o result_of<T(A1, A2, ..., AN)>::type, używane w celu określenia typu zwracanej reference_wrapper<T>::operator():

Implementacja może ustalić człon typu za pośrednictwem wszelkich środków, które daje dokładny typ F wyrażenie (T1, T2, ..., tN) dla podanych typów. [Uwaga: Chodzi o to, że implementacje mogą wykorzystywać specjalne klamerki kompilator końcem Uwaga]

a następnie paragraf 3:

Jeżeli F nie jest obiektem funkcja zdefiniowana przez biblioteki standardowej, a jeśli implementacja nie może określić typu wyrażenia f (t1, t2, ..., tN) lub jeśli wyrażenie jest źle sformułowane, implementacja powinna użyć następującego procesu do określenia elementu typu:

  • Jeśli F jest prawdopodobnie klasą kwalifikowaną typu cv bez elementu przeponowego er o nazwie result_type lub jeśli typename F::result_type nie jest typem:
    • Jeśli N = 0 (brak argumentów), typ jest nieważny.
    • Jeśli n> 0, typ jest typename F::template result<F(T1, T2,..., TN)>::type

Komunikat o błędzie jest artefaktem próbować te wchodzą zwrotnych. Podaj typedef dla result_type do int i powinien działać, jak sądzę. Zauważ, że w C++0x jest inaczej. Nie opiera się na szablonie result_type lub result, ponieważ może on używać decltype.

Jeśli z <functional> nie powiedzie się z MSVC10 w trybie C++ 0x, to pachnie jak błąd, powiedziałbym. Ale może ktoś jeszcze wie, co się dzieje. Może (ale nie ma gwarancji) pracować z <tr1/functional> w trybie C++ 0x, jeśli ten nagłówek wybierze sposób decltype zamiast ::result_type. Chciałbym typedef result_type - w ten sposób myślę, że to powinno zawsze działać niezależnie od tego, czy używany jest nagłówek tr1 czy nagłówek c++0x.


zauważyć również, że boost::tr1 mówi w jego dokumentacji, która nie obsługuje operator wywołania funkcji (ale to tylko wspiera niejawne konwersje do T&).

+1

Tak, to naprawić problem: D To jest szkoda dla vs2010 dla tej regresji w stosunku do poprzedniej wersji z 2008 roku ... Najnowszy projekt ściśle wymaga, aby kompilator mógł automatycznie rozpoznać typ zwrotu. WG21/docs/papers/2009/n3000.pdf Paragraf 20.7.4 –