C++ 模板特化改变了 constexpr 规则?

标签 c++ templates

我正在使用 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 版本的一部分。

关于C++ 模板特化改变了 constexpr 规则?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71615353/

相关文章:

c++ - 为什么我的模板化 operator== 没有被使用?

c++ - 始终在 QTableView 的单元格中显示 QComboBox

c++ - 通过枚举模板参数编译时间类模板选择

c++ - 在调试 session 期间获取有关匿名异常的数据

C++实体组件系统和使用模板访问组件

c++ - 模板忽略了常量(为什么?)

c++ - 通过 performSelector 传递指针或整数类型

c++ - 错误系统:使用正确路径时:错误的文件描述符(BOOST::FileSystem)

xcode - 如何在 Xcode 中包含 cocos2d-x 模板?

c++ - 类成员函数的返回值类型