2014-07-03 12 views
13
#include <vector> 

struct C 
{ 
    std::vector<int> v; 
    decltype(v.begin()) begin() { return v.begin(); } 
    decltype(v.end()) end() { return v.end(); } 
}; 

Clang ++ hat kein Problem, aber MSVC 2013 gibt den folgenden Fehler:Warum hat Visual Studio 2013 Probleme mit diesem Deklinationstyp?

error C2228: left of '.begin' must have class/struct/union 
+5

Finden Sie unter http://StackOverflow.com/A/11235245/103167, warum dieser Codierungsstil in jedem Compiler gebrochen ist, und Sie sollten trailing-return type für 'declltype' auf Members von' this' verwenden. –

Antwort

19

Dies ist ein known bug ist. Der Compiler akzeptiert den Code, wenn Sie stattdessen einen abschließenden Rückgabetyp verwenden.

struct C 
{ 
    std::vector<int> v; 
    auto begin() -> decltype(v.begin()) { return v.begin(); } 
    auto end() -> decltype(v.end()) { return v.end(); } 
}; 

Wie der Bug-Report sagt, ist eine andere Arbeit um unter Verwendung von:

struct C 
{ 
    std::vector<int> v; 
    decltype(std::declval<decltype(v)>().begin()) begin() { return v.begin(); } 
    decltype(std::declval<decltype(v)>().end()) end() { return v.end(); } 
}; 

Aber wie @BenVoigt Punkte in den Kommentaren aus, read this answer dafür, warum der hintere Rückgabetyp die bevorzugte Option sein sollte.

+2

Was ist mit Trailing-Return-Typ, die der Fehlerbericht sagt funktioniert gut? 'auto begin() -> decltype (v.begin()) {return v.begin(); } 'Sieht mir viel besser aus, wenn es richtig funktioniert –

+0

@BenVoigt Einverstanden, aktualisiert die Antwort. Und danke, dass ich Litb mit dieser Antwort verlinkt habe, mir war diese Einschränkung nicht bewusst. – Praetorian