std::forward 具有模板化重载函数
std::forward with templated overloaded function
我不知道为什么编译器会给我有关模板实例化的警告。
这是一段运行良好并正确输出 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();
}
但我需要将它与模板化类型一起使用。所以将 "overloaded" 函数修改为
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),并且控制台输出右值 2 次而不是先输出左值。
我做错了什么?
T&&
等模板比较特殊。他们被称为"forwarding references"。他们对以下函数有特殊的扣除规则:
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&&
模板是一种反模式。当您想捕获所有内容时,这些特殊模板会派上用场。
我不知道为什么编译器会给我有关模板实例化的警告。
这是一段运行良好并正确输出 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();
}
但我需要将它与模板化类型一起使用。所以将 "overloaded" 函数修改为
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),并且控制台输出右值 2 次而不是先输出左值。
我做错了什么?
T&&
等模板比较特殊。他们被称为"forwarding references"。他们对以下函数有特殊的扣除规则:
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&&
模板是一种反模式。当您想捕获所有内容时,这些特殊模板会派上用场。