如何从返回显式类型元组的函数初始化const基本类型变量
用户提供的代码示例:
#include <tuple> #include <cstddef> #include <iostream> using namespace std; std::tuple<const size_t, const size_t> returnSize_T_Tuple() { const size_t i = 2; const size_t j = 3; return {i, j}; } std::tuple<const int, const int> returnIntTuple() { const int i = 2; const int j = 3; return {i, j}; } int main(){ // const size_t s_i; // error: uninitialized ‘const s_i’ [-fpermissive] // std::tie(const size_t x, const size_t y) = returnSize_T_Tuple(); // error: expected primary-expression before ‘const’ const auto [x,y] = returnSize_T_Tuple(); const size_t [a,b] = returnSize_T_Tuple(); // error: structured binding declaration cannot have type ‘const size_t’ {aka ‘const long unsigned int’} cout << "x = " << x << "; " << "a = " << a; }
为什么显式指定单个类型的结构化绑定会报错?
结构化绑定的语法规则要求,声明处的类型必须是数组类型、满足tuple-like要求的类类型(比如std::tuple),或者是有public数据成员的聚合类——简单说,这个类型得是能被拆解成多个元素的“容器/聚合体”,而不是单个标量类型(比如const size_t)。
你写的const size_t [a,b]里,const size_t是单个unsigned整数类型,不是数组也不是tuple类,编译器根本不知道怎么把右侧的tuple拆解成这个类型的元素,所以直接报错。
如何用显式类型初始化const变量?
方法1:显式指定完整的tuple类型做结构化绑定
如果你非要显式写出类型,得把整个tuple的类型写出来,而不是单个元素的类型,同时加上const限定:
// 显式指定tuple的完整类型 const std::tuple<const size_t, const size_t> [a,b] = returnSize_T_Tuple();
其实这里的const直接加在绑定前,和const auto的效果完全一致,只是显式写出了tuple的类型而已。
方法2:用std::get直接提取元素初始化const变量
如果不想用结构化绑定,也可以直接调用std::get从返回的tuple里提取对应位置的元素,直接初始化const变量:
const size_t a = std::get<0>(returnSize_T_Tuple()); const size_t b = std::get<1>(returnSize_T_Tuple());
这种方式完全显式指定了变量的类型,也满足你初始化const变量的需求。
方法3:先捕获tuple再拆解
先把函数返回的tuple存起来,再用std::get或者结构化绑定拆解:
const auto t = returnSize_T_Tuple(); const size_t a = std::get<0>(t); const size_t b = std::get<1>(t); // 或者用结构化绑定 const auto [a,b] = t;
为什么std::tie绑定const变量不行?
std::tie的参数要求是可修改的左值引用(T&),它的作用是把变量绑定到tuple的元素上,允许后续修改这些变量。但你要绑定的是const变量,const变量是不可修改的左值,类型是const T&,和std::tie要求的参数类型不匹配,而且语法上也不允许在std::tie的参数列表里声明带const的变量,所以这种写法必然报错。
内容的提问来源于stack exchange,提问作者heretoinfinity

