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

community! I am trying to apply the new features of C ++ 14 and unexpectedly encountered an error while trying to pass the const char [] argument to the function 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 compiler message is that the function is trying to return an array (why do this?). If I change the return type of the function to void, it will be compiled. If I pass an argument of another type (not an 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
source share
2 answers

This is a GCC error.

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

g ++ supports the unlimited common functions specified in Β§ 4.1.1.2 and Β§5.1.1 of N3889: Basic Lite. In short, auto can be used as a type specifier in a parameter declaration of any function of a declarator to introduce a template for an implicit function parameter similar to common lambdas.

N3889 is an early working draft of TS concepts. The above section, 5.1.1, is partially read.

A common function is indicated by the declarator of the auto function or the name of the concept as part of the type specifier in its Parameter declaration of the subordinate clause. [Example:

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

- end of example]

The use of auto or a conceptual name in a parameter-declaration-sentence is interpreted as the use of a parameter of a type having the same restrictions and a named concept. [Note. The exact mechanism to achieve this is unspecified. - end note] [Example: general function declared below

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

Equivalent to next ad

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

- end of example]

Note that this conversion should not affect the return type; it remains auto - this means that it will be displayed.

Given these rules, an autofunc should be equivalent

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

which would be valid. Instead, he received an interpretation as

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

causes an error, because when performing the entire T transfer, the output ends as an array type.

This is ironic, as 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 clearly not the case on GCC 4.9.

+5
source
 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) ^ 

This is the error you are getting. He says that the return type matches the parameter. This is because you have decltype(auto) , and the implementation replaces "func" with:

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

instead:

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

I have no explanation why this is happening ... but the error itself is clear.

This works great:

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

Once you do this const reference , this will not work. I still don't know why else.

EDIT:

The only way to make it work 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; } 

Create a temporary variable for the string and pass it instead. OR adding a parameter to a pointer to a char array. It seems like it’s hard for him to say whether it is β€œconst char [15]” or β€œconst char *”.

In any case, the above will work.

+2
source

Source: https://habr.com/ru/post/982432/


All Articles