c++ - 当用作概念的默认参数时,非重载函数会产生未解决的重载错误
问题描述
背景
模板模板参数的模板参数应该是类模板或别名模板的名称,表示为 id-expression。
这意味着不可能将函数模板作为默认模板模板参数传递。
正如预期的那样,以下代码片段:
template <typename>
void func() {}
template <template <typename> typename Wrapper = decltype(&func)>
struct Foo {};
导致以下错误(Clang):
error: default template argument for a template template parameter must be a class template
template <template <typename> typename Wrapper = decltype(&func)>
问题
但是,当函数模板作为受概念约束的默认模板模板参数提供时,会引发不同的错误:
void placeholder() {}
void func(std::invocable auto f) {}
template <typename Fn, typename FnArg>
concept FooConcept = std::is_invocable_v<FnArg>;
template <FooConcept<decltype(&placeholder)> Wrapper = decltype(&func)>
struct Foo {};
令人惊讶的是,这会产生一个重载错误:
铛error: reference to overloaded function could not be resolved; did you mean to call it?
template <FooConcept<decltype(&placeholder)> Wrapper = decltype(&func)>
海合会
error: 'decltype' cannot resolve address of overloaded function
99 | template <FooConcept<decltype(&placeholder)> Wrapper = decltype(&func)>
当decltype(&func)
被一个仿函数替换,它是一个类模板,
void placeholder() {}
template <typename Fn, typename FnArg>
concept FooConcept = std::is_invocable_v<FnArg>;
struct Functor {
auto operator()(std::invocable auto f) -> void {}
};
template <FooConcept<decltype(&placeholder)> Wrapper = Functor>
struct Foo {};
这编译没有错误。
问题
- 这是否源自背景中的错误但显示不同的消息?
- 如果不是,它为什么会显示与重载函数相关的错误?
解决方案
- 这是否源自背景中的错误但显示不同的消息?
不,这完全无关。背景错误是试图将类型作为默认参数传递给期望模板的参数:它只是错误类型的参数。
- 如果不是,它为什么会显示与重载函数相关的错误?
您尝试做的事情减少到:
void func(auto f) {}
using T = decltype(&func); // error
没有一种类型func
-func
不是函数,而是函数模板。它可用于实例化具有许多不同类型的许多不同函数。这里没有足够的信息来选择正在选择的重载。
您必须手动选择,如:
using T = decltype(static_cast<void(*)(int)>(func)); // ok
另请参阅此问题。
decltype(&func)
旨在作为默认参数的参数受约束这一事实invocable
无关紧要 - 该信息不参与选择所需参数func
所需的重载决议。
提供Functor
作为默认参数可以正常工作,因为这已经是一种类型,所以它可以正常工作。
推荐阅读
- javascript - 语音识别
- python - 如何将同时数据写入来自 Python 中的多个线程的 csv 文件
- python - 在 Windows 上使用 Nuitka 将 Python 脚本编译为独立的 dll,以便在 c# 中使用
- relational-algebra - 关系代数题(措辞有问题,请阅读说明)
- python - 在 for 循环中使用 if 语句
- linkedin - 指向通过 UGC 发布 API 创建的linkedIn 共享的 URL/永久链接?
- c# - 如何有效地删除文件中的最后一行并为大文件附加新文本?
- java - 无法将转换为布尔值的字符串插入 JAVA 中的 if 语句
- google-apps-script - 仅当复选框为真时运行脚本
- rsa-archer-grc - 如何在工具栏内容下的订阅通知内的现有字段中添加字段?