[英]How to instantiate a static member of a template class with integer template parameter?
我找到了有关如何使用类型参数实例化 C++ 模板类的 static 成员的问题的各种答案(例如https://stackoverflow.com/a/3229904/2995726 ),但我无法将其应用于模板 class integer 个参数。
我试过这个,但模板参数有一个默认值的额外复杂性:
$ cat test.cc
#include <iostream>
template<unsigned int a = 33>
class A
{
public:
static unsigned char x;
static unsigned int f(void) { return x + a; }
};
// Instantiate template
template class A<>;
// Attempts to instantiate static member:
// unsigned char A<>::x;
// template<> unsigned char A<>::x;
// template<unsigned int> unsigned char A<>::x;
int main(void)
{
A<>::x = 3;
std::cout << A<>::f() << std::endl;
}
当我尝试使用 g++ 10.2 编译它时,出现 linker 错误:
$ g++ -std=c++14 -o foo test.cc
/usr/bin/ld: /tmp/ccXGU1fT.o: in function `main':
test.cc:(.text+0x7): undefined reference to `A<33u>::x'
/usr/bin/ld: /tmp/ccXGU1fT.o: in function `A<33u>::f()':
test.cc:(.text._ZN1AILj33EE1fEv[_ZN1AILj33EE1fEv]+0x7): undefined reference to `A<33u>::x'
collect2: error: ld returned 1 exit status
三个注释行是尝试实例化 static 成员变量。 当我启用以下行时:
unsigned char A<>::x;
然后会发生这种情况:
test.cc:16:15: error: specializing member ‘A<>::x’ requires ‘template<>’ syntax
16 | unsigned char A<>::x;
| ^~~~
使用这一行:
template<> unsigned char A<>::x;
再次导致 linker 错误:
$ g++ -std=c++14 -o foo test.cc
/usr/bin/ld: /tmp/ccmw49ld.o: in function `main':
test.cc:(.text+0x7): undefined reference to `A<33u>::x'
/usr/bin/ld: /tmp/ccmw49ld.o: in function `A<33u>::f()':
test.cc:(.text._ZN1AILj33EE1fEv[_ZN1AILj33EE1fEv]+0x7): undefined reference to `A<33u>::x'
collect2: error: ld returned 1 exit status
最后一行:
template<unsigned int> unsigned char A<>::x;
导致此错误:
$ g++ -std=c++14 -o foo test.cc
test.cc:18:43: error: template parameters not deducible in partial specialization:
18 | template<unsigned int> unsigned char A<>::x;
| ^
test.cc:18:43: note: ‘<anonymous>’
test.cc:25: confused by earlier errors, bailing out
问题是目前我们在 class 模板中只有 static 数据成员x
的声明。 所以要解决这个问题,我们需要为 static 数据成员x
提供一个定义。 对于 C++17,您可以使用inline
在 class 模板中定义static
数据成员x
,这样就不再需要 static 数据成员的类外定义,如下所示:
template<unsigned int a = 33>
class A
{
public:
inline static unsigned char x{}; //inline used here
static unsigned int f(void) { return x + a; }
};
对于 Pre-C++17 标准,我们必须为 static 数据成员提供类外定义:
//out-of-class definition for Pre-C++17
template<unsigned int a>
unsigned char A<a>::x{};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.