C++14 auto deduction error: function returns an array

本秂侑毒 提交于 2019-12-11 07:29:41

问题


community! I'm trying to apply new C++14 features and unexpectedly encountered on error while I was attempting to pass the const char[] argument to the function given below:

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

I don't know why,but the compilier's message is that function tries to return an array (why would it do this?). If I change function's return type to void It'll be compiled. If I pass an argument of another type(not array) It will be compiled. What is the problem with arrays?

Error message

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

回答1:


This is a GCC bug.

auto is not allowed in function parameter declarations in C++14. This syntax is added by the Concepts Lite TS. The GCC 4.9 release notes say that

G++ supports unconstrained generic functions as specified by §4.1.2 and §5.1.1 of N3889: Concepts Lite Specification. Briefly, auto may be used as a type-specifier in a parameter declaration of any function declarator in order to introduce an implicit function template parameter, akin to generic lambdas.

N3889 is an early working draft of the concepts TS. The cited section, 5.1.1, reads in part

A generic function is denoted by function declarator having auto or a concept-name as part of the type-specifier in its parameter-declaration-clause. [Example:

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

end example ]

The use of auto or a concept-name in the parameter-declaration-clause shall be interpreted as the use of a type-parameter having the same constraints and the named concept. [ Note: The exact mechanism for achieving this is unspecified. — end note ] [Example: The generic function declared below

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

Is equivalent to the following declaration

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

end example ]

Note that this transformation is not supposed to affect the return type; it remains auto - meaning that it will be deduced.

Given these rules, autofunc's declaration should have been equivalent to

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

which would have been valid. Instead, it got interpreted as

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

causing an error since, with all the forwarding you are doing, T ends up getting deduced as an array type.

This is particular ironic since GCC 4.9's own notes (cited above) say that

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

which is demonstrably not the case on GCC 4.9.




回答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)
            ^

Is the error you're getting. It says the return type is the same as the parameter. That's because you have decltype(auto) and the implementation replaces the "func" with:

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

instead of:

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

I don't have an explanation why it does this.. but the error itself is clear.

This works fine:

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

As soon as you make it a const reference, it will not work. I still don't know why yet.

EDIT:

The only way I can get it working at all is to do:

#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 creating a temporary variable for the string and passing that instead.. OR casting the parameter to a pointer to a char array. It seems that it has a hard time telling whether it is a "const char[15]" or "const char*".

Either way, the above will work.



来源:https://stackoverflow.com/questions/28380494/c14-auto-deduction-error-function-returns-an-array

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!