是否有模板推导指南可以启用变量 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
在内部,构造函数可以自己执行该转换,而不是将其推送到函数签名中。
一旦构造函数看起来像这样:
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
.所以摆脱它并列出你实际在做什么。您的构造函数采用 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++ - 在 C++-17 中,此构造函数是否有可能的模板推导指南?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64419931/