【发布时间】:2023-04-07 13:17:01
【问题描述】:
我正在编写一种“异步工厂”,其中具体对象的耗时构造被推迟到std::async 任务。
每个AsyncFactory 都会存储一个指向对象的智能指针。
[这不是工厂模式最正确的应用,而是为了一个MWE]。
#include <future>
#include <memory>
#include <type_traits>
#include <cassert>
/**
* @param I is the interface type
* @param Ptr is the memory handler. Default = unique; optional = shared
*/
template <class I, template<class> class Ptr = std::unique_ptr>
class AsyncFactory
{
/**
* @param C - the concrete type for the interface I
* @param Ts - the variadic params
*/
template <class C, typename... Ts>
void _future_reload(Ts&&... params)
{
if (std::is_same<Ptr, std::unique_ptr>()) // line21
{
ptr = std::make_unique<C>(std::forward<Ts>(params)...);
}
else
{
if (std::is_same<Ptr, std::shared_ptr>()) // line27
{
ptr = std::make_shared<C>(std::forward<Ts>(params)...);
}
else
{
static_assert(0, "unacceptable type for smart pointer");// line33
}
}
}
public:
Ptr<I> ptr;
AsyncFactory() :
ptr(nullptr)
{}
/**
* @param C - the concrete type. Default: the interface type
* @param Ts - the variadic params
*/
template <class C = I, typename... Ts>
void reload(Ts&&... params)
{
std::future<void> fReload =
std::async(std::launch::async,
&AsyncFactory::_future_reload<C, Ts...>, this,
std::forward<Ts>(params)...);
}
};
class BaseVirtual
{
virtual void foo() = 0;
};
class DerivedConcrete :
public BaseVirtual
{
void foo() override {;}
};
int main()
{
AsyncFactory<BaseVirtual, std::shared_ptr> fac;
fac.reload<DerivedConcrete>();
}
智能指针出现问题。我必须为unique/shared 指针调用不同的makers。但是g++ -std=c++14 停在
f.cpp: In member function ‘void AsyncFactory<I, Ptr>::_future_reload(Ts&& ...)’:
f.cpp:21:44: error: type/value mismatch at argument 1 in template parameter list for ‘template<class, class> struct std::is_same’
if (std::is_same<Ptr, std::unique_ptr>())
^
f.cpp:21:44: note: expected a type, got ‘Ptr’
f.cpp:21:44: error: type/value mismatch at argument 2 in template parameter list for ‘template<class, class> struct std::is_same’
f.cpp:21:44: note: expected a type, got ‘unique_ptr’
f.cpp:27:45: error: type/value mismatch at argument 1 in template parameter list for ‘template<class, class> struct std::is_same’
if (std::is_same<Ptr, std::shared_ptr>())
^
f.cpp:27:45: note: expected a type, got ‘Ptr’
f.cpp:27:45: error: type/value mismatch at argument 2 in template parameter list for ‘template<class, class> struct std::is_same’
f.cpp:27:45: note: expected a type, got ‘shared_ptr’
f.cpp:33:9: error: static assertion failed: unacceptable type for smart pointer
static_assert(0, "unacceptable type for smart pointer");
【问题讨论】:
-
您需要指定 std::unique_ptr 的内容才能成为类型
-
我认为你最好做部分特化(可能有一个共同的基础以避免重复),而不是试图在一个函数体中枚举可能的
Ptr参数。 -
实际上,整个
_future_reload都违反了[temp.res]/8。这就是为什么 line33 被突出显示 -
在 C++14 中,
std::unique_ptr不会匹配template<class> class Ptr,因为第二个默认模板(删除器)。 -
@Jarod42 评论的演示:godbolt.org/g/tNiYB1
标签: c++ templates c++14 metaprogramming smart-pointers