2014-03-05 138 views
1

我有以下代碼:c + +返回類型和類型名稱

#include <iostream> 
#include <tuple> 

struct H 
{ 
    static const int Index = 0; 
}; 

struct V 
{ 
    static const int Index = 1; 
}; 

struct Slice 
{ 
    Slice(): Value(5) { } 

    int Value; 
}; 

class Dimension 
{ 
public: 

    template<class D> 
    Slice& Slice() // causes compiler error 
    //::Slice& Slice() // compiles ok 
    { 
     return std::get<D::Index>(slices); 
    } 

    template<class D> 
    ::Slice const& Slice() const 
    { 
     return std::get<D::Index>(slices); 
    } 

private: 

    typedef std::tuple<::Slice, ::Slice> SlicesT; 
    SlicesT slices; 
}; 


int main(int, char*[]) 
{ 
    Dimension d; 

    std::cout << d.Slice<V>().Value << std::endl; 

    d.Slice<V>().Value = 10; // error here 

    std::cout << d.Slice<V>().Value << std::endl; 
} 

這使此錯誤在VS2012:error C3892: 'd' : you cannot assign to a variable that is const

我可以通過限定第一功能返回類型(如在評論修復它大綱)。但我真的不明白這裏發生了什麼。這是一個編譯器錯誤還是真正危險的代碼?

+2

您必須符合'::',因爲您有一個與該類型名稱相同的函數。 – Adam

+0

@亞當是的。我想我只是感到驚訝,編譯器找到函數名並在類型名到達返回類型之前隱藏它。 – user673679

回答

3

clang給出了一個更友好的警告:

main.cpp:33:5: error: must use 'struct' tag to refer to type 'Slice' in this scope 
    Slice const& Slice() const 
    ^
    struct 
main.cpp:26:12: note: struct 'Slice' is hidden by a non-type declaration of 'Slice' here 
    Slice& Slice() // causes compiler error 
     ^
1 error generated. 

struct Slice::Slice在讓編譯器都工作知道你說的類型。在MSVC上,出於某種原因,struct Slice不起作用,因此您必須使用範圍解析運算符。