2013-01-22 238 views
1

下面的代碼有什麼問題? g ++和clang的最新版本都會給出錯誤。我相信我在這裏錯過了一些基本的東西。靜態類成員

#include <iostream> 

struct Z 
{ 
    static const int mysize = 10; 
}; 

Z f2(); 

int main() 
{ 
    std::cout << f2()::mysize << std::endl; 
} 

這裏的動機是能夠使用如下代碼使用模板找出數組的大小。我知道有很多方法,但只是偶然發現了這個想法。

template<int N> struct S 
{ 
    enum { mysize = N }; 
}; 

template<class T, int N> S<N> f(T (&)[N]); 

int main() 
{ 
    char buf[10]; 
    std::cout << f(buf)::mysize << std::endl; 
} 

回答

4

f2()返回一個值,而不是一個類型。你需要使用.操作上的返回值,而不是::

::運營商需要在左側具名的類型,而.允許被命名的值。您的表達f2()未命名類型,因此它不能與::一起使用。

作爲一個側面說明,在問題中稍微詳細一點,我們可能能夠解決您的實際問題。

+0

但不是我的表達式與Z :: mysize相同? – Chubsdad

+0

更新了激勵示例 – Chubsdad

+0

@Chubsdad'::'應該在其左側有一個類(結構)或名稱空間,但在您的示例中,它有一個由'f2'返回的類型爲'Z'的對象。使用'.'來引用對象的'mysize'成員。 – Sergey

-1

我覺得你需要在課堂申報後加const int Z::mysize;

+0

我認爲,使用現代版本的C++ /現代C++編譯器,您可以在類定義中定義常量,靜態變量。 – Xymostech

0

程序中有兩個錯誤:

  1. 您正在使用::操作員訪問對象的成員。改爲使用operator .(「點」);
  2. 您聲明函數f2()並在未定義的情況下調用它(這會給您一個鏈接器錯誤)。

而且,由於static成員變量類(Z在這種情況下),你並不需要一個對象來訪問它的所有實例之間共享;

這裏是你如何能解決你的程序:

#include <iostream> 

struct Z 
{ 
    static const int mysize = 10; 
}; 

Z f2() { return Z(); } 

int main() 
{ 
    // Don't need an object to access a static variable... 
    std::cout << Z::mysize << std::endl; 

    // ...but if you really want to, do it this way... 
    std::cout << f2().mysize << std::endl; 
} 
0

你爲什麼不使用這種方式來找出陣列由模板大小:

#include <iostream> 

template<int N> struct S 
{ 
    enum { mysize = N }; 
}; 

template<class T, int N> int f1(T (&)[N]) 
{ 
     return N; 
} 

int main() 
{ 
    char buf[10]; 
    std::cout << f1(buf) << std::endl; 

} 

而這一次更接近你的變種:

template<class T, int N> S<N> f(T (&)[N]) 
{ 
     S<N> foo; 
     return foo; 
} 


int main() 
{ 
    char buf[10]; 
    std::cout << f(buf).mysize << std::endl; 
} 

無論如何,你將需要從f和ACC返回一個對象通過.,而不是::。 但第二個變體更可能會變慢,因爲第一個變體是完全編譯時,但在第二個變體中,編譯器可能會錯過優化,並且不會優化foo的運行時創建。