我有以下可以编译的代码(GCC7、C++17):
template<typename T>
struct NDArrayHostAllocatorNew
{
static T* allocate(std::size_t size) {
return new T[size];
}
static void deallocate(const T* ptr){
delete [] ptr;
}
};
template<typename T, template<typename TT> typename Alloc>
class NDArrayHost
{
public:
typedef Alloc<T> allocator_type;
NDArrayHost(std::size_t size);
private:
T* m_data;
};
template<typename T, template<typename TT> typename Alloc>
NDArrayHost<T, Alloc>::NDArrayHost(std::size_t size)
{
m_data = allocator_type::allocate(size);
}
这是我的问题:
如果我使用
T
而不是TT
,我会收到一个T
遮蔽另一个的错误。好吧,公平地说,但就我而言,我希望T
与TT
相同。我怎样才能强制执行呢?我想我可以以某种方式使用 std::enable_if 和 std::is_same 吗?但在这种情况下,代码就会变得过于繁琐。有没有什么毛茸茸的解决方案?我几乎看不到带有模板模板参数的代码。我是否在做一些不被认为是良好做法的事情?
我不太喜欢这个解决方案的语法。有没有更好的方法来做同样的事情,但代码更干净/更简单?
虽然带有模板模板参数的代码非常丑陋,但是很明显可以理解这段代码的作用:它只是允许用户指定他/她自己的机制来为
NDArrayHost
对象。尽管这符合一个完全不同/单独的问题:如果您认为我完全错误地解决了这个问题,请随时向我指出更好的解决方案(只要不是像Thrust
那样非常复杂。
最佳答案
一种方法是根据类型 T
和 Alloc
声明基本模板,然后仅提供合法的部分特化。
#include <cstddef>
#include <memory>
template<typename T>
struct NDArrayHostAllocatorNew
{
static T* allocate(std::size_t size) {
return new T[size];
}
static void deallocate(const T* ptr){
delete [] ptr;
}
};
/*
* declare the base template in terms of T and allocator
*/
template<typename T, typename Alloc>
class NDArrayHost;
/*
* only provide legal specialisations
*/
template<class T, template<class> class Alloc>
class NDArrayHost<T, Alloc<T>>
{
public:
typedef Alloc<T> allocator_type;
NDArrayHost(std::size_t size);
private:
T* m_data;
};
template<class T, template<class> class Alloc>
NDArrayHost<T, Alloc<T>>::NDArrayHost(std::size_t size)
{
m_data = allocator_type::allocate(size);
}
如果我们愿意,我们可以添加专门化以在 T 不匹配时提供诊断:
/* specifically disallow illegal specialisations */
template<class T, class U, template<class> class Alloc>
class NDArrayHost<T, Alloc<U>>
{
static_assert(std::is_same<T, U>(), "meh");
};
测试...
int main()
{
NDArrayHost<int, NDArrayHostAllocatorNew<int>> h(10);
// fails with static assert
// NDArrayHost<int, NDArrayHostAllocatorNew<double>> h2(10);
}
关于c++ - 如何在 C++17 中强制模板和模板参数之间的约束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46723598/