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

Static template member array sizeof used in method

本文关键字:成员 数组 sizeof 静态 方法      更新时间:2023-10-16

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

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文件中使用它就可以工作。但是如何在多个文件中使用它呢?

如果我把初始化的头,链接将失败,因为:

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

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

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

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

如果你把struct模板定义留在头文件中,你可能会在初始化数据的翻译单元中强制模板实例化,并使用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:

#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

您可以尝试将其封装在未命名的名称空间中,这将提供内部链接并绕过' Foo<0>::data'的多个定义

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