C++ 模板专业化更改 constexpr 规则?
C++ template specialization changes constexpr rules?
我正在使用 g++ (GCC) 11.2.0。
下面这段代码
#include <vector>
#include <iostream>
template<int size>
constexpr std::vector<int> get_vector() {
return std::vector<int> (size);
}
int main() {
std::cout << get_vector<5>().size() << std::endl;
}
编译成功,执行时输出5
。正如我所料。
但是,如果我添加专业化
#include <vector>
#include <iostream>
template<int size>
constexpr std::vector<int> get_vector() {
return std::vector<int> (size);
}
template<>
constexpr std::vector<int> get_vector<2>() {
return std::vector<int> (2);
}
int main() {
std::cout << get_vector<5>().size() << std::endl;
}
编译失败并产生错误
another.cpp: In function ‘constexpr std::vector<int> get_vector() [with int size = 2]’:
another.cpp:10:28: error: invalid return type ‘std::vector<int>’ of ‘constexpr’ function ‘constexpr std::vector<int> get_vector() [with int size = 2]’
10 | constexpr std::vector<int> get_vector<2>() {
| ^~~~~~~~~~~~~
In file included from /usr/include/c++/11.2.0/vector:67,
from another.cpp:1:
/usr/include/c++/11.2.0/bits/stl_vector.h:389:11: note: ‘std::vector<int>’ is not literal because:
389 | class vector : protected _Vector_base<_Tp, _Alloc>
| ^~~~~~
/usr/include/c++/11.2.0/bits/stl_vector.h:389:11: note: ‘std::vector<int>’ has a non-trivial destructor
为什么会这样?
如果您查看 compiler support,您会发现 gcc 从版本 12 开始支持 constexpr std::vector
。正如您告诉我们您使用的是 gcc 11.2,它根本没有在库中实现。
您可以在 godbolt 上使用 gcc 和 clang 的主干版本看到它按预期工作。对于 gcc,它将成为 gcc 12.x 版本的一部分。
我正在使用 g++ (GCC) 11.2.0。
下面这段代码
#include <vector>
#include <iostream>
template<int size>
constexpr std::vector<int> get_vector() {
return std::vector<int> (size);
}
int main() {
std::cout << get_vector<5>().size() << std::endl;
}
编译成功,执行时输出5
。正如我所料。
但是,如果我添加专业化
#include <vector>
#include <iostream>
template<int size>
constexpr std::vector<int> get_vector() {
return std::vector<int> (size);
}
template<>
constexpr std::vector<int> get_vector<2>() {
return std::vector<int> (2);
}
int main() {
std::cout << get_vector<5>().size() << std::endl;
}
编译失败并产生错误
another.cpp: In function ‘constexpr std::vector<int> get_vector() [with int size = 2]’:
another.cpp:10:28: error: invalid return type ‘std::vector<int>’ of ‘constexpr’ function ‘constexpr std::vector<int> get_vector() [with int size = 2]’
10 | constexpr std::vector<int> get_vector<2>() {
| ^~~~~~~~~~~~~
In file included from /usr/include/c++/11.2.0/vector:67,
from another.cpp:1:
/usr/include/c++/11.2.0/bits/stl_vector.h:389:11: note: ‘std::vector<int>’ is not literal because:
389 | class vector : protected _Vector_base<_Tp, _Alloc>
| ^~~~~~
/usr/include/c++/11.2.0/bits/stl_vector.h:389:11: note: ‘std::vector<int>’ has a non-trivial destructor
为什么会这样?
如果您查看 compiler support,您会发现 gcc 从版本 12 开始支持 constexpr std::vector
。正如您告诉我们您使用的是 gcc 11.2,它根本没有在库中实现。
您可以在 godbolt 上使用 gcc 和 clang 的主干版本看到它按预期工作。对于 gcc,它将成为 gcc 12.x 版本的一部分。