c++ - 静态表生成适用于 GCC 但不适用于 clang; clang 有问题吗?

标签 c++ templates language-lawyer static-members partial-specialization

我曾经写过一些代码,在编译时为一些模板元编程生成一个静态表/数组(这个想法是 C 风格的字符串可以在编译时构建(它们只是 char 数组))。这个想法和代码基于 David Linanswer :

#include <iostream>

const int ARRAY_SIZE = 5;

template <int N, int I=N-1>
class Table : public Table<N, I-1>
{
public:
    static const int dummy;
};

template <int N>
class Table<N, 0>
{
public:
    static const int dummy;
    static int array[N];
};

template <int N, int I>
const int Table<N, I>::dummy = Table<N, 0>::array[I] = I*I + 0*Table<N, I-1>::dummy;

template <int N>
int Table<N, 0>::array[N];

template class Table<ARRAY_SIZE>;

int main(int, char**)
{
    const int *compilerFilledArray = Table<ARRAY_SIZE>::array;
    for (int i=0; i < ARRAY_SIZE; ++i)
        std::cout<<compilerFilledArray[i]<<std::endl;
}

使用 GCC 4.9.2 编译此代码有效:

$ g++-4.9 -Wall -pedantic b.cpp
$ ./a.out
0
1
4
9
16

不过,Clang 3.5 会提示:

$ clang++ -Wall -pedantic b.cpp
Undefined symbols for architecture x86_64:
  "Table<5, 0>::dummy", referenced from:
      ___cxx_global_var_init in b-b8a447.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

dummyarray 都是在 Table 类(声明它们的地方)之外给出的定义。据我所知,这应该满足链接器要求。

这是 clang 的错误吗?

最佳答案

每个主要和部分特化静态数据成员都必须单独定义。

template <int N, int I>
const int Table<N, I>::dummy = …;

这里唯一定义的是Table<N, I>::dummy - 主要特化静态数据成员。 [temp.class.spec.mfunc]/11:

Class template partial specialization members that are used in a way that requires a definition shall be defined; the definitions of members of the primary template are never used as definitions for members of a class template partial specialization.

这也意味着 GCC 在这里是错误的。这是一个错误。
无论哪种方式,添加

template <int N>
const int Table<N, 0>::dummy = 0;

应该可以正常编译。


1) 特别是,在与上述引述相同的部分:

The template parameter list of a member of a class template partial specialization shall match the template parameter list of the class template partial specialization.
The template argument list of a member of a class template partial specialization shall match the template argument list of the class template partial specialization.

这意味着用于定义偏特化及其成员的参数列表必须相同。否则该成员永远不会被定义。

关于c++ - 静态表生成适用于 GCC 但不适用于 clang; clang 有问题吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27320993/

相关文章:

c++ - C++98 标准在哪里指定对静态成员的调用何时依赖于模板?

javascript - 纯函数 : Does "No Side Effects" Imply "Always Same Output, Given Same Input"?

c++ - 在 C++ 中混淆 char 数组和指针

c++ - 如何在 C++ 预处理器中检测 g++ 和 MinGW?

c++ - 从 std::binary_function (或 std::unary 函数)继承有什么好处?

c++ - 在派生类中绑定(bind)非静态模板化成员函数

c++ - 甚至在 C++ 中执行空循环吗?

html - 如何将 Go HTML 模板嵌入到代码中?

c++ - 在 C++ 中使用模板

c - C中临时对象的有效类型