我不知道为什么编译器会给我关于模板实例化的警告。
这是一段运行得很好的代码并正确输出lvalue / rvalue:
//template<typename T>
void overloaded(const /*T*/std::string& in)
{
std::cout << "lvalue" << std::endl;
}
//template<typename T>
void overloaded(/*T*/std::string&& in)
{
std::cout << "rvalue" << std::endl;
}
template<typename T>
void pass(T&& in)
{
overloaded(std::forward<T>(in));
}
int main()
{
std::string a;
pass(a);
pass(std::move(a));
getchar();
}
但我需要使用模板类型。所以将“重载”函数修改为
template<typename T>
void overloaded(const T& in)
{
std::cout << "lvalue" << std::endl;
}
template<typename T>
void overloaded(T&& in)
{
std::cout << "rvalue" << std::endl;
}
给出模板实例化警告,(对我来说,它的明确T应该是std :: string),控制台输出rvalue 2次而不是lvalue。
我做错了什么?
答案 0 :(得分:1)
T&&
等模板很特别。他们被称为&#34;转发参考&#34;。他们对以下功能有特殊的扣除规则:
template<typename T>
void overloaded(T&& in)
假设overloaded
没有超载。如果将std::string
类型的左值表达式传递给overloaded
,T
将推导为std::string&
。如果您将std::string
类型的右值表达式传递给overloaded
,T
将推导为std::string
。您可以使用此知识来执行此操作:
template<typename T>
void overloaded(T&& in)
{
if (std::is_lvalue_reference<T>::value)
std::cout << "lvalue" << std::endl;
else
std::cout << "rvalue" << std::endl;
}
通常,使用其他任何内容来重载T&&
模板是一种反模式。当你想抓住所有东西时,这些特殊模板会派上用场。