为何std::remove_reference未移除引用?代码问题求助
关于std::remove_reference在std::visit中类型匹配失败的问题
你遇到的问题是:第一段C++代码中通过decltype(arg)得到的类型T为int&时能正常打印输出;但第二段使用std::remove_reference<T>与int进行类型匹配时,无论匹配int、int&还是int&&都无法触发打印,想知道原因。
第一段代码
#include <vector> #include <sys/types.h> using namespace std; using var_t = std::variant<int, long, double, std::string>; int main(int argc, char* argv[]) { std::vector<var_t> vec = {10}; for(auto v : vec) { std::visit([](auto&& arg) { using T = decltype(arg); // if (std::is_same_v<std::remove_reference<T>, int>) { if (std::is_same_v<T, int&>) { cout<<"int "<<arg<<endl; } }, v); } return 0; }
第二段代码
#include <vector> #include <sys/types.h> using namespace std; using var_t = std::variant<int, long, double, std::string>; int main(int argc, char* argv[]) { std::vector<var_t> vec = {10}; for(auto v : vec) { std::visit([](auto&& arg) { using T = decltype(arg); if (std::is_same_v<std::remove_reference<T>, int>) { cout<<"int "<<arg<<endl; } }, v); } return 0; }
问题原因
你犯了一个典型的模板类型使用错误:std::remove_reference<T>本身是一个模板类,而不是直接的类型。要获取移除引用后的实际类型,你需要访问它的嵌套成员类型type,也就是std::remove_reference<T>::type;如果是C++14及以后的版本,还可以用更简洁的别名std::remove_reference_t<T>。
在第二段代码里,std::is_same_v<std::remove_reference<T>, int>本质是在比较std::remove_reference<int&>这个模板类和int类型,这两者完全不是一回事,所以条件永远为假,自然不会触发打印逻辑。
修正后的判断条件可以写成两种形式:
// C++11及以上版本写法 if (std::is_same_v<typename std::remove_reference<T>::type, int>) // C++14及以上更简洁的写法 if (std::is_same_v<std::remove_reference_t<T>, int>)
额外补充:在std::visit的lambda中,auto&& arg是通用引用。由于你用for(auto v : vec)遍历的是拷贝出来的值类型,arg会被推导为int&(通用引用绑定到左值时,推导结果为左值引用),所以T是int&,std::remove_reference_t<T>就是int,此时修正后的条件就会成立,正常打印输出。
内容的提问来源于stack exchange,提问作者Shivanshu Arora
相关产品推荐
相关产品推荐

