使用' std::move '自动返回类型推导
auto return type deduction with `std::move`
下面程序的输出都是1A
,经过c++filt -t
后都是A
。我可以看到,当使用std::move
返回时,返回类型被推断为值类型而不是右值引用类型。对于大多数用std::move
返回的用例来说,这是有意义的,但是这样做的原因是什么?std::move
返回右值引用,但为什么返回类型自动推断为值类型?
#include <iostream>
#include <memory>
#include <utility>
#include <typeinfo>
struct A
: std::unique_ptr<int>
{
auto f()
{
return A();
}
auto g()
{
return std::move(A());
}
};
int main()
{
std::cout << typeid(decltype(A().f())).name() << ' ';
std::cout << typeid(decltype(A().g())).name() << ' ';
std::cout << typeid(A).name() << 'n';
}
你有两个独立的问题:
- 您用来检查返回类型的工具不适合使用。
typeid
条带参考然后顶级cv-资格;typeid(int)
,typeid(const int)
和typeid(const int&&)
是一样的。要测试实际类型,请使用std::is_same
;提振。TypeIndex有type_id_with_cvr
。在执行template<class T> class TD;
时,还有一个技巧,尝试定义TD</*type to be checked*/>
类型的变量,并从编译器生成的错误消息中读出类型。
但是这里是无害的;f()
和g()
确实返回A
的值:
-
auto f() { return /* stuff */; }
使用auto
规则,它从不推导引用类型。这实际上通常是您想要的-您真的不想意外地返回对已经死亡的东西的引用-这确实是您的g()
在返回引用时会做的事情!
要得到"perfect return ",使用decltype(auto)
.
参见typeid operator on cppreference:
typeid( type )
-表示类型为type
的std::type_info
对象。如果type
是引用类型,则结果指向被引用的类型。
换句话说,typeid()将丢弃/忽略任何顶级引用限定符。
为了避免这种情况,您可以将类型包装在某些东西中,例如像void(your_type)
这样的函数签名,它会给出A&&
的例子:http://coliru.stacked-crooked.com/a/d6af3eff8216246f
我可以看到,当使用std::move返回时,返回类型被推断为值类型而不是右值引用类型。对于大多数用std::move返回的用例来说是有意义的,但是这样做的原因是什么?Std::move返回一个右值引用,但是为什么返回类型自动推断为值类型?
普通auto
类型推导与普通模板参数推导相同(std::initializer_list
除外)。换句话说,除非使用了通用引用&&
,否则auto
永远不会推导出引用。
decltype(auto)
执行与auto
相似的类型演绎,但还增加了额外的decltype
演绎规则,允许演绎l值和r值引用。如果您希望将其作为引用推导出来,那么您可能会喜欢将其用于返回类型。
typeid(expression)
查询expression
的static类型信息。对于任何引用,包括std::move()
返回的右值引用,这意味着查询引用引用的对象的类型,而不是引用本身的类型。
- 如何获取std::result_of函数的返回类型
- <Windows>为什么 std::thread::native_handle 返回类型为"long long unsigned int"的值,而不是 void*(又名 HANDLE)?
- 推导 std::vector::back() 的返回类型
- 在模板化成员函数的返回类型中使用 std::enable_if 时的编译器差异
- 如何使用 std::invoke_result_t 获取函数的返回类型
- 错误:为"运算符 std::string {aka std::__cxx11::basic_string}"指定的返回类型<char>
- 使用 std::smatch 作为返回类型将导致匹配器变为" 00 00 00 00 00 00 00"
- std::绑定variadic模板和自动返回类型
- 为什么C++哈希函数的返回类型是 std::size_t,而不是独立于平台的类型?
- std::function 中不允许引用返回类型吗?
- 如何在 c++ 中使用返回类型导出函数 std::map
- 返回类型 std::optional<std::variant<...>>
- std::d eclval vs crtp,无法从不完整类型推断方法返回类型
- 为什么C++ std::min_element 库函数接受采用布尔返回类型的函数对象的函子,而不是像 C 中那样的 in
- STD :: SETW,STD :: SETFILL等的真实返回类型是什么?
- 为什么必须STD ::访问具有单一返回类型
- C++14 'auto'能够获取函数返回类型,我们还需要 std::result_of<> 吗?
- 正确使用 std::enable_if 作为返回类型
- 为什么返回类型 std::reverse_iterator::operator[] 未指定
- 返回类型 std::bind 隐式转换为两个不同的显式构造函数