【发布时间】:2018-02-12 04:41:49
【问题描述】:
在编写一些模板代码时,我遇到了<unresolved overloaded function type> 错误,可以简化为以下内容。
template <int N>
auto bar()
{
return N;
}
int main(int, char* [])
{
auto foo = [] (auto func) {
return func();
};
foo(bar<3>);
}
错误是:
unresolved_overload.cpp: In function 'int main(int, char**)':
unresolved_overload.cpp:26:28: error: no match for call to '(main(int, char**)::<lambda(auto:1)>) (<unresolved overloaded function type>)'
std::cout << foo(bar<3>) << std::endl;
^
unresolved_overload.cpp:21:29: note: candidate: template<class auto:1> constexpr main(int, char**)::<lambda(auto:1)>::operator decltype (((const main(int, char**)::<lambda(auto:1)>*)((const main(int, char**)::<lambda(auto:1)>* const)0))->operator()(static_cast<auto:1&&>(<anonymous>))) (*)(auto:1)() const
auto foo = [] (auto func) {
^
unresolved_overload.cpp:21:29: note: template argument deduction/substitution failed:
unresolved_overload.cpp:26:28: note: couldn't deduce template parameter 'auto:1'
std::cout << foo(bar<3>) << std::endl;
^
unresolved_overload.cpp:21:29: note: candidate: template<class auto:1> main(int, char**)::<lambda(auto:1)>
auto foo = [] (auto func) {
^
unresolved_overload.cpp:21:29: note: template argument deduction/substitution failed:
unresolved_overload.cpp:26:28: note: couldn't deduce template parameter 'auto:1'
std::cout << foo(bar<3>) << std::endl;
如果我们将自动返回替换为显式返回类型int,则该示例将正常编译。
为什么自动返回会遇到这些问题?我研究了模板参数推导和替换,但搜索基本上没有结果。我认为这可能与模板实例化/等的顺序有关,但无法理解它......
【问题讨论】:
-
gcc 无法编译显示的代码,报告此错误消息,但
auto z=bar<3>; foo(z);似乎工作正常,这让我把矛头指向了编译器。 -
在 Clang 中编译也失败了。无论如何,我怀疑你不能这样做的原因与你不能做
transform(..., max<int>)的原因是一样的。您需要显式地转换您想要的重载或将其包装在仿函数中。 -
@user167921 我实际上并没有用 Clang 测试这个,但 Godbolt 表明它确实编译了godbolt.org/g/jjapKh。您能否详细说明一下显式转换重载?
-
在模板函数定义中使用decltype
-
我应该认为这应该编译。从技术上讲,您应该使用
&bar<3>,但它在 gcc 中没有任何区别。令人惊讶的是,它在 MSVC 19.00.23506 中编译。也在 Clang 7.0 中编译