C++:使用decltype派生函数返回类型

her*_*nnk 2 return-type decltype c++11 c++14

以下是真正的C++ 14应用程序的(过度)简化摘录.出于可维护性的原因,我不想明确指定返回类型foo().我知道C++ 14可以很好地推断出函数的返回类型auto.但真正的应用程序需要函数内部的返回类型.所以我需要它.

以下代码片段编译(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;
    }
Run Code Online (Sandbox Code Playgroud)

但是如果我使用函数声明的"注释掉"版本,我会得到以下诊断:

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
                                                                    ^
Run Code Online (Sandbox Code Playgroud)

怎么了?不是std::wstring::size_type一种类型?不std::remove_reference转换std::basic_string<wchar_t>&成平原std::wstring

Mor*_*enn 5

std::remove_reference没有size_type会员,std::wstring有.您可以访问std::wstring使用std::remove_reference<decltype(s)>::type.因此,您真正需要的返回类型是:

std::remove_reference <decltype (s)>::type::size_type
Run Code Online (Sandbox Code Playgroud)

由于您使用的是C++ 14,因此可以使用std::remove_reference_t,这是为了可读性而引入的别名模板快捷方式:

std::remove_reference_t <decltype (s)>::size_type
Run Code Online (Sandbox Code Playgroud)

编辑:正如@Cassio在评论中所指出的那样,由于你使用的是C++ 14,你可以让函数推导出auto自动删除引用的返回类型:

auto foo (std::wstring &s)
    {
    return s.length ();
    }
Run Code Online (Sandbox Code Playgroud)

也就是说,你真的应该考虑什么时候你真的想要这样做.许多人在有意义时优先采用明确的回报类型.