我有以下类,方法签名如下:
class Foo
{
public:
std::vector<std::string> barResults(const std::vector<std::string>&, const std::vector<std::string>&);
}
Run Code Online (Sandbox Code Playgroud)
在实现文件中,我有这个:
std::vector<std::string> Foo::barResults(const std::vector<std::string>& list1, const std::vector<std::string>& list2)
{
std::vector<std::string> results;
// small amount of implementation here...
return results;
}
Run Code Online (Sandbox Code Playgroud)
所以我想,让我们看看我是否可以通过一些自动魔法来简化这个功能签名,因为它会变成一个"满满一行"!所以我试过这个......
class Foo
{
public:
auto barResults(const std::vector<std::string>&, const std::vector<std::string>&);
}
auto Foo::barResults(const std::vector<std::string>& list1, const std::vector<std::string>& list2)
{
std::vector<std::string> results;
// small amount of implementation here...
return results;
}
Run Code Online (Sandbox Code Playgroud)
现在忽略了这样一个事实:是的,我可以使用"使用命名空间std"来修剪它,我想知道为什么编译器给了我一个错误"返回'auto'的函数在定义之前不能使用".
我个人原本会认为编译器很容易推断出该方法的返回类型,但在这种情况下它似乎并非如此.当然,您可以使用尾随返回类型修复它,如下所示:
class Foo
{
public:
std::vector<std::string> barResults(const std::vector<std::string>&, const std::vector<std::string>&) -> std::vector<std::string>;
}
Run Code Online (Sandbox Code Playgroud)
但是如果你使用上面的话,那就不比以前好了.因此,除了"使用命名空间std"之外,有没有更好的方法来执行上述操作,为什么编译器不能在此实例中推断出返回类型?或者甚至,它是否依赖于如何调用此方法导致编译器无法确定返回类型.
这里的问题是包含文件如何工作的问题.你的错误:
返回'auto'的函数在定义之前不能使用
意味着在您正在使用您的函数的文件中,其定义(即实现)在使用之前不在文件中的任何位置.这意味着使用该函数编译代码的编译器无法推导出函数返回类型,因为这需要访问定义(实现).最可能的原因是函数的定义(实现)在其自己的源(.cpp,.c等)文件中,不包括在内.为了更全面地理解这一点,我建议阅读这个答案,也许这个答案也是如此.
为了解决这个标题问题,缩短该签名的最简单方法可能是使用typedef.更具体地说,您可以在适当的位置添加以下代码,前提是适当的范围(我将其添加为您的类中的公共成员):
typedef std::vector<std::string> strvec;
Run Code Online (Sandbox Code Playgroud)
这允许您重新编写方法签名,因为它更易于管理:
strvec barreuslts(const strvec&, const strvec&)
Run Code Online (Sandbox Code Playgroud)