方法中使用的静态模板成员数组sizeof

Static template member array sizeof used in method

我有一个带有静态成员数组的模板 class 和一个需要数组大小的方法。

template <int i>
struct Foo {
    static int data[];
    static int size() {
        return sizeof(data) / sizeof(data[0]);
    }
};

我想为每个模板专业化以不同方式初始化数组。

template <>
int Foo<0>::data[] = { 0, 1, 2 };

只要我只在一个 cpp 文件中使用它,它就可以工作。但是如何在多个文件中使用呢?

如果我将初始化放到 header,链接将失败,因为:

multiple definition of `Foo<0>::data'

如果我将它放入其中一个 cpp 文件中,其他文件将无法编译,因为:

invalid application of ‘sizeof’ to incomplete type ‘int []’

我对不将数组更改为 std::vector 的解决方案感兴趣。

您可以尝试将它包含在一个未命名的命名空间中,这将提供一个内部链接并绕过 `Foo<0>::data' 的多重定义

namespace{
template <int i>
struct Foo {
    static int data[];
    static int size() {
        return sizeof(data) / sizeof(data[0]);
    }
};
}

如果您将结构模板定义留在 header 中,您可能会在初始化数据的翻译单元中强制模板实例化,并在使用时使用 extern 阻止它,例如:

// imp.cc: initialization and instantiation
template <>
int Foo<0>::data[] = { 0, 1, 2 };
template struct Foo<0>;

// main.cc: extern declaration and usage:
template<> extern int Foo<0>::size ();
... Foo<0>::size () ...

(我用一个小例子和 clang 测试了它。)

这对我有用:

Foo.h:

#ifndef FOO_H
#define FOO_H

template <int i>
struct Foo {
    static int data[];
    static int size() {
        return sizeof(data) / sizeof(data[0]);
    }
};

#endif

Foo-0.h:

#ifndef FOO_0_H
#define FOO_0_H

#include "Foo.h"

// Provide declarations of the members for 0
template <> int Foo<0>::data[];
template <> int Foo<0>::size();

#endif

Foo-0.cpp:

#include "Foo-0.h"

// Define the members for 0
template <> int Foo<0>::data[] = {10, 20, 30};
template <> int Foo<0>::size()
{
   return sizeof(data) / sizeof(data[0]);
}

main.cpp:

#include <iostream>

#include "Foo-0.h"

int main()
{
    std::cout << Foo<0>::data[0] << std::endl;
    std::cout << Foo<0>::size() << std::endl;
};

输出:

10
3