Cou*_*per 5 templates sfinae enable-if template-meta-programming c++11
是否有"足够"可靠的方法来检测模板参数中的分配器.也就是说,我需要一些is_allocator类型特征,可用于enable_if:
假设有一个类模板future(带模板参数T):
// Default ctor with allocator
template <class Alloc, class... Args
class Enable = typename std::enable_if<
is_allocator<Alloc>::value
and std::is_constructible<T, Args...>::value
>::type
>
future(const Alloc& a, Args&&... args)
: _shared_value(std::allocate_shared<T>(a, std::forward<T>(args...))
{
}
// Default ctor (without allocator)
template <class... Args
class Enable = typename std::enable_if<
std::is_constructible<T, Args...>::value
>::type
>
future(Args&&... args)
: _shared_value(std::make_shared<T>(std::forward<T>(args...))
{
}
Run Code Online (Sandbox Code Playgroud)
在这里,_shared_value是一个std::shared_pointer<T>.
is_allocator标准库中没有这样的特性,但您可以自己编写一个:
#include <vector>
#include <utility>
template <class T>
class is_allocator
{
typedef char yes;
typedef long no;
// you can extend this with many more checks on the allocator interface
template <class C> static yes check( decltype(std::declval<C>().allocate(0)) );
template <class C> static no check(...);
public:
enum { value = sizeof(check<T>(0)) == sizeof(yes) };
};
int main()
{
std::vector<int> v { 1, 2 };
using V = decltype(v)::value_type;
using A = decltype(v)::allocator_type;
static_assert(!is_allocator<V>::value, "");
static_assert( is_allocator<A>::value, "");
}
Run Code Online (Sandbox Code Playgroud)
实例.
上面的代码allocate(size_type)通过在decltype()表达式中调用该函数来检查类型是否具有成员函数.如果存在这样的函数,check<T>(0)则将在enum表达式中选择该重载并且value将成为true.作为检查,您可以static_assert在模板参数上进行此操作std::vector.
显然,可以改善由具有一堆细粒度特征的这种做法has_allocate,has_deallocate和所有其他必要的成员函数组成的标准整个分配器要求.完成后,您可以定义is_allocator逻辑和所有这些细粒度特征.