9

以下代码对我来说很好:

    #include <stdio.h>

    template <typename T>
    struct A
    {
        static float m_kA[];
    };

    template <typename T>
    float A<T>::m_kA[] = {1.0f, 2.0f, 3.0f};

    int main()
    {
        printf("%d\n", 
            sizeof(A<unsigned int>::m_kA) /
            sizeof(A<unsigned int>::m_kA[0]));
        return 0;
    }

但是当我用 VC9 编译时出现以下错误

error C2070: 'float []': illegal sizeof operand

我希望这段代码能够编译。我错过了什么吗?有谁知道解决这种奇怪行为的方法(请注意,没有模板的完全相同的东西编译得很好并输出 3)。

请注意,删除模板不是一个选项,我制作了这个示例来重现我在代码中遇到的问题,我需要包含数组的类型作为模板。

谢谢

4

2 回答 2

7

它的定义很好。请注意,在类定义中,m_kA用 type 声明float[],这是一个不完整的类型,不能与sizeof. 在的定义中m_kA,重新声明了有类型float[3],之后就可以使用了sizeof。(8.3.4 规定了数组声明的含义。)

从 3.4.6 使用指令和命名空间别名 [basic.lookup.udir]:

10 在所有类型调整之后(在此期间 typedefs (7.1.3) 被其定义替换),所有引用给定变量或函数的声明指定的类型应相同,除了数组对象的声明可以指定数组类型因存在或不存在主要数组边界而异(8.3.4)。在类型标识上违反此规则不需要诊断。

从 3.9.2 复合类型 [basic.compound]:

6 [...]数组对象的声明类型可能是一个未知大小的数组,因此在翻译单元中的某个点不完整,稍后完成;这两个点的数组类型(“T 的未知边界数组”和“NT 数组”)是不同的类型。[...]

编译器问题的解决方法是直接声明m_kA完整的类型。另一个保持大小的静态成员也可能会有所帮助。

[我引用 C++11,但据我所知,C++03 遵循相同的规则。]

于 2012-09-18T21:16:44.043 回答
6

http://ideone.com/3ssVi

它用 G++ 编译得很好。

据我所见,它可能与此错误有关:

http://connect.microsoft.com/VisualStudio/feedback/details/759407/can-not-get-size-of-static-array-defined-in-class-template

于 2012-09-18T21:11:18.583 回答