首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++14自动推导错误:函数返回数组

C++14自动推导错误:函数返回数组
EN

Stack Overflow用户
提问于 2015-02-07 09:26:12
回答 2查看 851关注 0票数 1

社区!我试图应用新的C++14特性,但在尝试将const char[]参数传递给以下函数时意外地遇到了错误:

代码语言:javascript
复制
 decltype(auto) autofunc( const auto& a)
 {
     cout<<"Hello World\n";
     cout<<a<<endl;

 }


 auto lambd = [](const auto& word){  autofunc(std::forward< decltype(word) > (word));};

int main()
{


 lambd("Goodbye World\n");


    return 0;
}

我不知道为什么,但是compilier的消息是函数试图返回数组(为什么要这样做?)如果我将函数的返回类型更改为无效,它将被编译。如果我传递另一种类型的参数(不是数组),它将被编译。数组有什么问题?

错误消息

代码语言:javascript
复制
../../untitled6/main.cpp: In instantiation of '<lambda(const auto:3&)> [with auto:3 = char [15]]':
../../untitled6/main.cpp:74:25:   required from here
../../untitled6/main.cpp:68:84: error: no matching function for call to 'autofunc(const char [15])'
  auto lambd = [](const auto& word){  autofunc(std::forward< decltype(word) > (word));};
                                                                                    ^
../../untitled6/main.cpp:68:84: note: candidate is:
../../untitled6/main.cpp:60:17: note: template<class auto:2> decltype(auto) autofunc(const auto:2&)
  decltype(auto) autofunc( const auto& a)
                 ^
../../untitled6/main.cpp:60:17: note:   template argument deduction/substitution failed:
../../untitled6/main.cpp: In substitution of 'template<class auto:2> decltype(auto) autofunc(const auto:2&) [with auto:2 = char [15]]':
../../untitled6/main.cpp:68:84:   required from '<lambda(const auto:3&)> [with auto:3 = char [15]]'
../../untitled6/main.cpp:74:25:   required from here
../../untitled6/main.cpp:60:17: error: function returning an array
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-02-07 15:20:51

这是GCC的窃听器。

auto在C++14中的函数参数声明中是不允许的。这个语法是由概念Lite TS添加的。GCC 4.9发行说明

G++支持不受约束的泛型函数,如N3889:概念Lite规范的§4.1.2和§5.1.1所述。简单地说,auto可以用作任何函数声明器的参数声明中的类型说明符,以便引入类似于泛型lambdas的隐式函数模板参数。

N3889是TS概念的早期工作草案。引来的第5.1.1条部分读作

泛型函数由具有auto或概念名称的函数声明符表示,作为其参数-声明-子句中类型说明符的一部分。示例: auto f(auto x);// Ok void ( Sortable & c);// Ok (假设可排序名称是一个概念) -最后一个例子 在参数声明子句中使用auto或概念名称应解释为使用具有相同约束和命名概念的类型参数。注:实现这一目标的确切机制未具体说明。-尾注

注意,这个转换不应该影响返回类型;它仍然是auto --这意味着它将被推导出来。

考虑到这些规则,autofunc的声明应该等同于

代码语言:javascript
复制
template<class T>
decltype(auto) autofunc( const T& a) { /* ... */ }

这应该是有效的。相反,它被解释为

代码语言:javascript
复制
template<class T>
T autofunc( const T& a) { /* ... */ }

导致一个错误,因为在进行所有转发时,T最终被推断为数组类型。

这是特别讽刺的,因为GCC 4.9自己的笔记(上面引用)说,

//以下两个函数声明是等价的auto ( auto ){返回x++;}模板自动索引(T){返回x++;}

GCC 4.9号上的显然不是这样的

票数 5
EN

Stack Overflow用户

发布于 2015-02-07 09:36:23

代码语言:javascript
复制
error: no matching function for call to 'func(const char [15])'
  auto lambd = [](const auto& word){  func(word);};
                                               ^
note: candidate is:

template<class auto:1> 
decltype(auto) func(const auto:1&)

decltype(auto) func( const auto& a)
            ^

是你所犯的错误。它表示返回类型与参数相同。这是因为您有decltype(auto),实现将"func“替换为:

代码语言:javascript
复制
template<class T>
T func(const T& a)

而不是:

代码语言:javascript
复制
template<class T, class R>
R func(const T& a);

我无法解释为什么会这样。但错误本身是明显的。

这样做很好:

代码语言:javascript
复制
#include <iostream>

using namespace std;

decltype(auto) func(const auto &a)
{
     cout<<"Hello World\n";
     cout<<a<<endl;
}


 auto lambd = [](const auto word){  func(std::forward<decltype(word)>(word));};

int main()
{
    lambd("Goodbye World\n");
    return 0;
}

一旦你把它变成一个const reference,它就不能工作了。我还是不知道为什么。

编辑:

我唯一能让它发挥作用的方法就是:

代码语言:javascript
复制
#include <iostream>

using namespace std;

decltype(auto) func(const auto &a)
{
     cout<<"Hello World\n";
     cout<<a<<endl;
}


 auto lambd = [](const auto &word){  func(std::forward<decltype(word)>(word));};

int main()
{
    lambd((const char*)"Goodbye World\n");   
    return 0;
}

也就是为字符串创建一个临时变量并将其传递给..。或将参数转换为指向char数组的指针。似乎很难判断它是"const char15“还是"const char*”。

不管是哪种方式,上述方法都会奏效。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28380494

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档