C ++ 14自动扣除错误:函数返回一个数组

时间:2015-02-07 09:26:13

标签: c++ arrays auto c++14

社会! 我正在尝试应用新的C ++ 14功能,并在我尝试将 const char [] 参数传递给下面给出的函数时意外遇到错误:

 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的消息是函数试图返回一个数组(为什么会这样做?)。如果我将函数的返回类型更改为 void 它将被编译。如果我传递另一种类型的参数(不是数组)它将被编译。数组有什么问题?

错误消息

../../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

2 个答案:

答案 0 :(得分:5)

这是一个GCC错误。

C ++ 14中的函数参数声明中不允许使用

auto。这种语法由Concepts Lite TS添加。 GCC 4.9 release notes

  

G ++支持§4.1.2规定的无约束泛型函数   和N3889的§5.1.1:Concepts Lite规范。简而言之,auto可能   用作任何函数的参数声明中的类型说明符   声明器以引入隐式函数模板   参数,类似于通用lambdas。

N3889是TS概念的早期工作草案。引用的部分5.1.1部分读取

  

泛型函数由具有auto或的函数声明符表示    concept-name 作为 type-specifier 的一部分   参数声明子句。 [实施例

auto f(auto x); // Ok
void sort(Sortable& c); // Ok (assuming Sortable names a concept)
     

- 结束示例]

     

使用auto概念名称    parameter-declaration-clause 应解释为使用具有相同约束和命名概念的类型参数。 [注意:未实现此目的的确切机制。 - 结束   note ] [示例:下面声明的泛型函数

auto f(auto x, const Regular& y);
     

等同于以下声明

template<typename T1, Regular T2>
auto f(T1 x, const T2&);
     

- 结束示例]

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

鉴于这些规则,autofunc的声明应该等同于

template<class T>
decltype(auto) autofunc( const T& a) { /* ... */ }

本来是有效的。相反,它被解释为

template<class T>
T autofunc( const T& a) { /* ... */ }

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

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

// the following two function declarations are equivalent
auto incr(auto x) { return x++; }
template <typename T>
auto incr(T x) { return x++; }

在GCC 4.9上是demonstrably not the case

答案 1 :(得分:2)

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)并且实现取代了&#34; func&#34;用:

template<class T>
T func(const T& a)

而不是:

template<class T, class R>
R func(const T& a);

我没有解释为什么会这样做..但错误本身很清楚。

这很好用:

#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,就行不通。我还是不知道为什么。

修改

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

#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;
}

Aka为字符串创建一个临时变量并传递它。或者将参数转换为指向char数组的指针。似乎很难说它是否是一个&#34; const char [15]&#34;或&#34; const char *&#34;。

无论哪种方式,以上都可行。