c++ - 在 C++-17 中,此构造函数是否有模板推导指南?
问题描述
是否有模板推导指南可以将变量c
推导出为类型bar<baz>
,就像变量一样b
?
#include <vector>
#include <functional>
template<typename T>
struct foo {
using container = std::vector<T>;
using creator = std::function<container()>;
};
template<typename T>
struct bar
{
bar(typename foo<T>::creator) { }
};
struct baz : public foo<baz> {
static baz::container make_it() { return {}; }
};
int main() {
bar<baz> b(baz::make_it);
bar c(baz::make_it); // What is the deduction guide to mimic b?
}
解决方案
这里的困难是由于参数和被推导的类型之间的关系非常脆弱。由于对函数参数的不必要限制,它也是不必要的。
我看不出你为什么特别需要在std::function
这里参加。您已经在模板中;您可以采用任何可调用类型,只要它可以用零参数调用并返回适当类型的容器。所以……就那样做吧。
即使类型要在std::function
内部存储 a,构造函数也可以自己执行转换,而不是将其塞入函数签名中。
一旦构造函数看起来像这样:
template<typename T>
struct bar
{
template<typename Func>
bar(Func &&f) { }
};
然后可以编写一个演绎指南来创建关于 和 之间关系的Func
期望T
。即:
template<typename Func>
bar(Func &&f) -> bar<std::invoke_result_t<Func>::value_type>;
这对任何可调用类型都有效,这些类型可以存储在std::function<container()>
.
但是,如果您不愿意使您的代码更合理地通用,您仍然可以这样做。事实上,上面的推导指南可以正常工作......只要你没有其他只接受一个参数的构造函数。那你就会有问题。
让您感到困惑的部分是foo
. 所以摆脱它并列出你实际在做什么。您的构造函数采用 a std::function
,可以使用零参数调用它以返回一个vector
纯右值,它value_type
是您要推断的类型。所以就这么说吧:
template<typename T>
bar(std::function<vector<T>()>) -> bar<T>;
是的,你必须重复你的定义baz::container
,但它有效。不,您不需要将匹配的构造函数设为模板。
事实上,你甚至不需要扣除指南:
template<typename T>
struct bar
{
bar(std::function<vector<T>()>) { }
};
推荐阅读
- c# - 如何解决警告 CS4014: Call is not waiting
- c# - 具有继承参数的重载函数
- php - 图表 - 当我通过 microsoft graph api 在 Outlook 中创建事件时,它返回 lastModifiedDateTime 连续变化几秒钟?
- django - Django LiveServerTestCase - 无法在多个测试中强制登录
- python - 引号内的 Jupyter 文件路径自动完成建议建议第三个引号
- mongodb - 使用python在mongo中将id替换为original_id
- php - 从控制器函数返回 iframe 视图
- postgresql - 我们可以在 postgresql.config 文件中设置多个端口吗?
- swift - Xcode - 改变标签的数量
- amazon-web-services - 如何在启用 NAT 的子网中使用 AWS VPC 终端节点?