为何参数依赖查找(ADL)对std::make_tuple不生效,而std::tie可省略std::?
问题与解答
问题
下面的代码中,直接使用tie而非std::tie是可行的,原因是参数依赖查找(ADL):
std::tuple<int, std::string> tup = std::make_tuple<int, std::string>(1, "a"); int i; std::string str; tie(i, str) = tup;
但为什么std::make_tuple必须添加std::限定符?
解答
要理清这个区别,核心得明白参数依赖查找(ADL)的生效逻辑:
- 当调用一个未加命名空间限定的函数时,编译器会自动去函数实参所属的命名空间里搜索该函数。
- 对于
tie(i, str) = tup这行代码:赋值操作的右操作数是tup,它的类型是std::tuple,属于std命名空间。编译器处理这个表达式时,会把std命名空间纳入tie函数的查找范围,因此能找到std::tie,不用显式写std::前缀。 - 对于
std::make_tuple<int, std::string>(1, "a"):这里的实参是int(内置类型)和const char*(内置类型范畴),内置类型没有关联的用户自定义命名空间,ADL无法触发。编译器只能在当前作用域和已导入的命名空间里查找make_tuple,如果没有提前using std::make_tuple,就必须显式加上std::限定符才能找到这个函数。
内容的提问来源于stack exchange,提问作者H.v.M.
相关产品推荐
相关产品推荐

