静态类成员

时间:2013-01-22 14:42:06

标签: c++

以下代码有什么问题?最新版本的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 个答案:

答案 0 :(得分:4)

f2()返回一个值,而不是一个类型。您需要在返回值而不是.

上使用::运算符

::运算符需要在左侧命名一个类型,而.允许命名一个值。您的表达式f2()未命名类型,因此无法与::一起使用。

作为旁注,在问题中稍微详细一些,我们可以解决您的真实问题。

答案 1 :(得分:0)

您的计划包含两个错误:

  1. 您正在使用::运算符访问对象的成员。请改用operator .(&#34; dot&#34;);
  2. 您声明函数f2()并在不定义的情况下调用它(这会给您一个链接器错误)。
  3. 此外,由于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;
    }
    

答案 2 :(得分: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返回一个对象并按.访问该成员,而不是::。 但是第二种变体更可能更慢,因为第一种变体是完全编译时,但在第二种变体中,编译器可能会错过优化,并且不会优化foo的运行时创建。

答案 3 :(得分:-1)

我认为您需要在课程声明后添加const int Z::mysize;