自C ++ 17起,现在实例化具有很多模板参数的类变得容易得多,这些模板参数可以从构造函数调用中自动推导。
在我的项目中,我有一个模板类的层次结构,可以将它们嵌套在一起,这会导致大量的类型名称,这就是为什么类模板参数推导如此出色的原因。
但是,我也使用静态工厂方法来简化类的动态构造(基本上,我只是返回包含新创建对象的shared_ptrs)。就像下面的示例一样
#include <iostream>
#include <memory>
template <typename T>
struct S {
const std::shared_ptr<T> m_t;
S(std::shared_ptr<T> t):
m_t {std::move(t)} {}
template<typename ...Args>
static S create(Args&&... args);
};
template <typename T>
template <typename ...Args>
std::shared_ptr<S<T>> S<T>::create(Args&&... args) {
return std::make_shared<S<T>>(std::forward<Args>(args)...);
}
int main() {
auto s1 = S{std::make_shared<int>(6)};
// auto s2 = S::create(std::make_shared<int>(5)); // DOESN'T work
}
我需要使用指针来启用多态性(除非有另一种不需要指针的方式-可能是CRTP),但是我看不到任何方法可以简化实例化过程,而无需指定返回的完整类型在某处物体。
答案 0 :(得分:2)
template <typename ...Args>
auto createS(Args&&... args) {
return std::make_shared<decltype(S{std::forward<Args>(args)...})>(std::forward<Args>(args)...);
}
int main() {
auto s1 = S{std::make_shared<int>(6)};
auto s2 = createS(std::make_shared<int>(5));
}
这应该确保推导类型与s1
完全相同。
实际上,您可以将其概括为任何类模板参数推导:
template <template<typename...> class Tmpl, typename ...Args>
auto make_shared_deduced(Args&&... args) {
return std::make_shared<decltype(Tmpl{std::forward<Args>(args)...})>(std::forward<Args>(args)...);
}
int main() {
auto s1 = S{std::make_shared<int>(6)};
auto s2 = make_shared_deduced<S>(std::make_shared<int>(5));
}
另请参阅standard proposal P1069R0。
您是否真的想要所有这些shared_ptr
我都不知道。可能只应在非常特殊的情况下使用它们,而不是一般那样。