2014-09-25 17 views
10

Czy std::reference_wrapper<T> może być niekompletne, tak jakby można było załatwić bez zakończenia?Czy można utworzyć instancję std :: reference_wrapper <T> gdzie T jest niekompletnym typem?

GCC 4.9 akceptuje następujące:

#include <functional> 

struct woof; 

struct test 
{ 
    test(woof& w) : w(w) {} 
    std::reference_wrapper<woof> w; 
}; 

struct woof 
{ 
    int a; 
}; 

int main() 
{ 
    woof w; 
    test t = w; // (braced-init would be better, but VS2012!) 
} 

Ale MSVS 2012 odrzuca go z następującym komunikatem:

Error 1 error C2139: 'hau': niezdefiniowany klasa nie jest dozwolony jako Argument typu kompilator wewnętrzną cechę '__is_abstract' c: \ program files (x86) \ Microsoft visual studio 11.0 \ VC \ include \ type_traits 755 1 test3

I podejrzewasz, że jest tak, ponieważ op() potrzebuje pełnego typu, ale standard nie wyświetla jako, aby określić którykolwiek sposób.

Które z tych implementacji spełnia standardowe mandaty?

+2

Nie mam pojęcia, ale mój zakład nie jest na MS –

+1

Należy zauważyć, że MSVC nie działa niezależnie od tego, co standard mówi: [Ten program] (http://coliru.stacked-crooked.com/a/5a8e28dc279da2e5) doesn ' t kompilacja na MSVC11 +, dzięki testowi 'is_abstract'. – Xeo

Odpowiedz

14

N3936 § 17.6.4.8 Inne funkcje [res.on.functions]:

1 W niektórych przypadkach (funkcje zamiennych, funkcjach obsługi, operacje na typach stosowanych do instancji standardowych komponentów Template Library), biblioteka standardowa C++ zależy od komponentów dostarczanych przez program C++. Jeśli te komponenty nie spełniają swoich wymagań, Standard nie nakłada żadnych wymagań dotyczących realizacji.

2 W szczególności, efekty nie są zdefiniowane w następujących przypadkach:

  • ...
  • jeśli niekompletna typu (3,9) stosuje się jako matrycę argumentu przy uruchamianiu element szablonu chyba specjalnie dozwolone dla tego składnika.

Szybkie skanowanie przez 20.9.3 klasy szablonu reference_wrapper [refwrap] ujawnia żadnego takiego szczególnego wyjątku dla reference_wrapper, więc program niezdefiniowane zachowanie. Obie implementacje są zgodne.

+1

Cholera, za wolno. +1 BTW: Myślę, że jest to przypadek, w którym niedozwolony typ powinien być dozwolony. – Deduplicator

+0

Wygląda na to, że jedynymi komponentami z tym wyjątkowym wyjątkiem są typy inteligentnych wskaźników. Wydaje mi się, że byłoby sensownym używanie go również dla 'reference_wrapper', ponieważ może być użyteczne i proste do wykonania (ponieważ zwykle jest to po prostu otoki wokół wskaźnika, jak inteligentne wskaźniki). Całe pytanie niekompletne jest bardzo słabym punktem w standardzie C++ (zarówno dla komponentów bibliotecznych, jak i reguł dotyczących szablonów), potrzebuje lepszych specyfikacji, takich jak klarowniejsze reguły i wymagana diagnostyka/błędy zamiast UB. –

+5

@Deduplicator Problem z dopuszczeniem niekompletnych typów polega na tym, że 'reference_wrapper' musi spełniać stary protokół' unary_function'/'binary_function' dla kompatybilności wstecznej.Aby to zrobić, musi zdefiniować różne typy w oparciu o typ parametru szablonu, np. [refwrap]/3: "Inicjacja szablonu ... powinna zdefiniować ...' argument_type' jako synonim dla 'T1' tylko wtedy, gdy typ' T' jest jednym z następujących: ... typ klasy z typ członka 'typ_argumentu', typ' T1' to 'T :: argument_type'.". – Casey

Powiązane problemy