例如,我得到了以下代码:
#include <memory>
class A {
public:
A(int i, float f){};
A(std::string){};
...
};
class B {
public:
B(int i){};
B(float f){};
...
};
std::unique_ptr<A> getA() {
if (some condition) {
return std::make_unique<A>(1,1.0);
} else if (some condition) {
return std::make_unique<A>("test");
}
}
std::unique_ptr<B> getB() {
if (some condition) {
return std::make_unique<B>(1);
} else if (some condition) {
return std::make_unique<B>(1.0);
}
}
我可以只写这样的代码return std::make_unique(1,1.0);
(否<A>
)吗?我认为编译器知道返回类型,只有A类的构造函数参数在这一行中很重要。那有什么办法可以省略类型参数?
我想要这个,因为在实际问题中,有很多类类型(带有长名称),并且每个类都有很多构造函数,每次返回时都写return make::unique<*type*>(*parameters*)
很烦人。
答案 0 :(得分:3)
您可以使用具有正确的unique_ptr转换程序的帮助程序类来获取它:
#include <tuple>
#include <memory>
#include <utility>
template <class ...Ts>
class unique_ptr_maker : private std::tuple<Ts...>
{
public:
using std::tuple<Ts...>::tuple;
template <class T>
operator std::unique_ptr<T>() &&
{
return move_it<T>(std::make_index_sequence<sizeof...(Ts)>());
}
private:
template <class T, std::size_t... Is>
std::unique_ptr<T> move_it(std::index_sequence<Is...>)
{
using parent = std::tuple<Ts...>;
return std::make_unique<T>(
std::forward<std::tuple_element_t<Is, parent>>(
std::get<Is>(*this))...);
}
};
template <class ...Ts>
unique_ptr_maker<Ts...> get_unique_maker(Ts &&...ts)
{
return unique_ptr_maker<Ts...>(std::forward<Ts>(ts)...);
}
那么用法是:
std::unique_ptr<B> getB() {
if (some condition) {
return get_unique_maker(1);
} else if (some condition) {
return get_unique_maker(1.0);
}
}
此解决方案分为两个阶段:
unique_ptr
的运算符。每当unique_ptr_maker恰好位于unique_ptr<T>
的位置时,就会调用此运算符。不幸的是,T
(来自unique_ptr<T>
)的构造函数的参数类型检查发生得很晚。结果,这些错误可能令人困惑。我看不到如何改善这种情况,因为无论如何在转换操作员之前都无法发现潜在的问题。
使它与仅移动参数一起使用。