C++:使用 decltype 派生函数 return 类型
C++: Deriving a function return type using decltype
以下是真实 C++14 应用程序的(过度)简化摘录。出于可维护性的原因,我不想明确指定 foo()
的 return 类型。我知道 C++14 可以自动推导 return 类型的函数 auto
。但是真正的应用程序需要函数内部的 return 类型。所以我手边需要它。
以下代码片段可以正常编译 (g++ 4.9.2):
#include <type_traits>
#include <iostream>
#include <string>
//auto foo (std::wstring &s) -> std::remove_reference <decltype (s)>::size_type
auto foo (std::wstring &s) -> decltype (s.length ())
{
return s.length ();
}
int main ()
{
std::wstring s {L"hello world"};
std::cout << foo (s) << "\n";
return 0;
}
但是如果我使用 "commented-out" 版本的函数声明,我会得到以下诊断信息:
foo.cpp:5:69: error: ‘size_type’ in ‘struct std::remove_reference<std::basic_string<wchar_t>&>’ does not name a type
auto foo (std::wstring &s) -> std::remove_reference <decltype (s)>::size_type
^
怎么了? std::wstring::size_type
不是一个类型吗?
std::remove_reference
不会将 std::basic_string<wchar_t>&
转换为普通的 std::wstring
吗?
std::remove_reference
没有 size_type
成员,std::wstring
有。您可以使用 std::remove_reference<decltype(s)>::type
访问 std::wstring
。因此,您的 return 类型真正需要的是:
std::remove_reference <decltype (s)>::type::size_type
由于您使用的是 C++14,因此可以使用 std::remove_reference_t
代替,这是为了提高可读性而引入的别名模板快捷方式:
std::remove_reference_t <decltype (s)>::size_type
编辑: 正如@Cassio 在评论中指出的那样,由于您使用的是 C++14,您不妨让函数推导 return 类型使用 auto
将自动删除引用:
auto foo (std::wstring &s)
{
return s.length ();
}
也就是说,你真的应该考虑 when you really want to do it。许多人更喜欢在有意义的情况下使用明确的 return 类型。
以下是真实 C++14 应用程序的(过度)简化摘录。出于可维护性的原因,我不想明确指定 foo()
的 return 类型。我知道 C++14 可以自动推导 return 类型的函数 auto
。但是真正的应用程序需要函数内部的 return 类型。所以我手边需要它。
以下代码片段可以正常编译 (g++ 4.9.2):
#include <type_traits>
#include <iostream>
#include <string>
//auto foo (std::wstring &s) -> std::remove_reference <decltype (s)>::size_type
auto foo (std::wstring &s) -> decltype (s.length ())
{
return s.length ();
}
int main ()
{
std::wstring s {L"hello world"};
std::cout << foo (s) << "\n";
return 0;
}
但是如果我使用 "commented-out" 版本的函数声明,我会得到以下诊断信息:
foo.cpp:5:69: error: ‘size_type’ in ‘struct std::remove_reference<std::basic_string<wchar_t>&>’ does not name a type
auto foo (std::wstring &s) -> std::remove_reference <decltype (s)>::size_type
^
怎么了? std::wstring::size_type
不是一个类型吗?
std::remove_reference
不会将 std::basic_string<wchar_t>&
转换为普通的 std::wstring
吗?
std::remove_reference
没有 size_type
成员,std::wstring
有。您可以使用 std::remove_reference<decltype(s)>::type
访问 std::wstring
。因此,您的 return 类型真正需要的是:
std::remove_reference <decltype (s)>::type::size_type
由于您使用的是 C++14,因此可以使用 std::remove_reference_t
代替,这是为了提高可读性而引入的别名模板快捷方式:
std::remove_reference_t <decltype (s)>::size_type
编辑: 正如@Cassio 在评论中指出的那样,由于您使用的是 C++14,您不妨让函数推导 return 类型使用 auto
将自动删除引用:
auto foo (std::wstring &s)
{
return s.length ();
}
也就是说,你真的应该考虑 when you really want to do it。许多人更喜欢在有意义的情况下使用明确的 return 类型。