[英]Combing two factory methods returning unique_ptr and shared_ptr into one in C++?
假設我有兩個工廠函數,一個返回std::unique_ptr
,另一個返回std::shared_ptr
:
template<class T, class... Args>
std::shared_ptr<T> createObjectS (Args... args)
{
// running some code
return std::make_shared<T>(args...);
}
template<class T, class... Args>
std::unique_ptr<T> createObjectU (Args... args)
{
// running some code
return std::make_unique<T>(args...);
}
是否可以使用模板元編程將這兩個功能組合為一個功能?
您可以使用SFINAE,但是后來我真的看不到將其包含在函數中的意義。 這是多余的。
#include <memory>
#include <type_traits>
template <class T, class... Args>
typename std::enable_if<
std::is_same<T, std::shared_ptr<typename T::element_type>>::value, T>::type
createObject(Args&&... args) {
// running some code
return std::make_shared<typename T::element_type>(std::forward<Args>(args)...);
}
template <class T, class... Args>
typename std::enable_if<
std::is_same<T, std::unique_ptr<typename T::element_type>>::value, T>::type
createObject(Args&&... args) {
// running some code
return std::make_unique<typename T::element_type>(std::forward<Args>(args)...);
}
int main() {
auto s = createObject<std::shared_ptr<int>>(1);
auto u = createObject<std::unique_ptr<int>>(1);
}
稍微緊湊一點,但具有相同范圍的枚舉基本上是相同的想法
#include <memory>
enum class ptr_t { shared, unique };
template <ptr_t P, class T, class... Args>
typename std::enable_if<P == ptr_t::shared, std::shared_ptr<T>>::type
createObject(Args&&... args) {
// running some code
return std::make_shared<T>(std::forward<Args>(args)...);
}
template <ptr_t P, class T, class... Args>
typename std::enable_if<P == ptr_t::unique, std::unique_ptr<T>>::type
createObject(Args&&... args) {
// running some code
return std::make_unique<T>(std::forward<Args>(args)...);
}
int main() {
auto s = createObject<ptr_t::shared, int>(1);
auto u = createObject<ptr_t::unique, int>(1);
}
在C ++ 17中,您當然會在兩種情況下都使用if constexpr
而不是SFINAE。
#include <memory>
enum class ptr_t { shared, unique };
template <ptr_t P, class T, class... Args>
decltype(auto) createObject(Args &&... args) {
// running some code
if constexpr (P == ptr_t::shared) {
return std::make_shared<T>(std::forward<Args>(args)...);
} else if (P == ptr_t::unique) {
return std::make_unique<T>(std::forward<Args>(args)...);
}
}
通過專業化,您可以:
template <typename T> struct FactoryImpl;
template <typename T> struct FactoryImpl<std::unique_ptr<T>>
{
template <typename ... Ts>
auto operator ()(Ts&&... args) const
{
return std::make_unique<T>(std::forward<Ts>(args)...);
}
};
template <typename T> struct FactoryImpl<std::shared_ptr<T>>
{
template <typename ... Ts>
auto operator ()(Ts&&... args) const
{
return std::make_shared<T>(std::forward<Ts>(args)...);
}
};
template<class T, class... Ts>
auto createObjectS (Ts&&... args)
{
return FactoryImpl<T>{}(std::forward<Ts>(args)...);
}
用法:
auto s = createObject<std::shared_ptr<MyObject>>(42);
auto u = createObject<std::unique_ptr<MyObject>>(42);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.