C++14 auto deduction error: function returns an array
C++14 auto deduction error: function returns an array
社区!
我正在尝试应用新的 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;
}
我不知道为什么,但编译器的消息是该函数试图 return 一个数组(它为什么要这样做?)。如果我将函数的 return 类型更改为 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
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)
^
是您遇到的错误。它说 return 类型与参数相同。那是因为你有 decltype(auto)
并且实现将 "func" 替换为:
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;
}
也就是为字符串创建一个临时变量并传递它。或者将参数转换为指向 char 数组的指针。好像很难判断是"const char[15]"还是"const char*".
无论哪种方式,上面的方法都有效。
这是一个 GCC 错误。
auto
在 C++14 的函数参数声明中是不允许的。此语法由 Concepts Lite TS 添加。 GCC 4.9 release notes 说
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 是概念 TS 的早期工作草案。引用的部分 5.1.1 部分内容为
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 ]
请注意,此转换不应影响 return 类型;它仍然是 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。
社区! 我正在尝试应用新的 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;
}
我不知道为什么,但编译器的消息是该函数试图 return 一个数组(它为什么要这样做?)。如果我将函数的 return 类型更改为 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
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)
^
是您遇到的错误。它说 return 类型与参数相同。那是因为你有 decltype(auto)
并且实现将 "func" 替换为:
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;
}
也就是为字符串创建一个临时变量并传递它。或者将参数转换为指向 char 数组的指针。好像很难判断是"const char[15]"还是"const char*".
无论哪种方式,上面的方法都有效。
这是一个 GCC 错误。
auto
在 C++14 的函数参数声明中是不允许的。此语法由 Concepts Lite TS 添加。 GCC 4.9 release notes 说
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 是概念 TS 的早期工作草案。引用的部分 5.1.1 部分内容为
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 belowauto 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 ]
请注意,此转换不应影响 return 类型;它仍然是 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。