C++ 在按固定大小模板化的不同大小缓冲区之间复制

C++ 在按固定大小模板化的不同大小缓冲区之间复制,c++,templates,C++,Templates,简化版本如下所示: template<int Size> struct IntBuffer {int items[Size];} IntBuffer<32> b1; IntBuffer<16> b2; b1 = b2; // I want this to be allowed as the size of b1 >= b2 b2 = b1; // I want this to be disallowed as the size of b2 <

简化版本如下所示:

template<int Size> struct IntBuffer {int items[Size];}

IntBuffer<32> b1;
IntBuffer<16> b2;


b1 = b2; // I want this to be allowed as the size of b1 >= b2
b2 = b1; // I want this to be disallowed as the size of b2 < b1
template <int Size> template <int RightSize>
IntBuffer<Size>& IntBuffer<Size>::operator=(const IntBuffer<RightSize>& right)
{
    static_assert(RightSize <= Size);
    // The real work.
}
template struct IntBuffer{int items[Size];}
intbufferb1;
intb2;
b1=b2;//我希望允许b1>=b2的大小
b2=b1;//我希望这是不允许的,因为b2的大小小于b1

编辑:看来我应该更清楚。。。如果由于前面提到的大小约束行为而不允许赋值,我想导致编译时错误。也没有boost,对可能没有完全C++11支持(如MSVC 2010)的编译器非常友好。

一种可能是使用一个模板重载赋值运算符,该模板将另一个缓冲区的大小作为参数。在实现中,如果可以使用C++11,您可以
static\u assert
您的需求:

template<int OtherSize>
IntBuffer<Size> & operator=(const IntBuffer<OtherSize> & other) {
    static_assert(OtherSize <= Size, "Error assigning to IntBuffers of different size: The size of the right hand side buffer shouldn't be larger than the one on the left hand side.");
    // (implementation)
}
(来源:)


演示:

首先,我要说的是,你这样做似乎并不直观。如果我正在阅读代码,并且看到了这一点,我会想,如果目标缓冲区的大小大于源缓冲区的大小,其他元素会发生什么情况(它们会被保留吗?它们会被清除吗?它们会以其他不确定的方式被更改吗?)。不仅如此,如果您将其限制为相同大小的缓冲区,编译器生成的复制构造函数和复制赋值运算符将正常工作,您不需要额外的工作

但是,如果在所有这些之后您仍然想要这样做,您可以创建自己的复制分配操作符。您必须编写自己的
static\u assert
(但您当然可以在C++98中这样做,因为boost已经做到了),因为您已经明确排除了我知道的两个地方,才能得到一个已经为您编写和调试过的地方(C++11和boost)

操作员可能如下所示:

template<int Size> struct IntBuffer {int items[Size];}

IntBuffer<32> b1;
IntBuffer<16> b2;


b1 = b2; // I want this to be allowed as the size of b1 >= b2
b2 = b1; // I want this to be disallowed as the size of b2 < b1
template <int Size> template <int RightSize>
IntBuffer<Size>& IntBuffer<Size>::operator=(const IntBuffer<RightSize>& right)
{
    static_assert(RightSize <= Size);
    // The real work.
}
模板
IntBuffer&IntBuffer::operator=(常量IntBuffer&right)
{

static_assert(RightSize实现复制构造函数/重载赋值运算符,并在其中应用您的逻辑。添加一个内部带有
static_assert
的赋值运算符模板(需要C++11支持)。我想知道为什么这些评论没有答案…抱歉,我本应该提到一些理想情况下友好的东西,VS2010支持完整的C++11支持
static\u assert
。这是我的大脑让我失望的SFINAE方法-我更新了问题,提到理想的C++11支持之前-我不想提及这一点。你可以模拟e static_断言pre-C++11,通过专门化一个带bool的模板。啊,好吧,我想我现在明白了…谢谢。@leems:我非常确定我应该标记答案,谢谢…只是用咖啡来做…我需要更浓的咖啡,因为我花了一点时间才意识到我认为你的前任的情况是错误的充足。我认为应该是:启用,如果这是正确的答案,如果我在C++11之前还没有理解如何实现它的话。但这是我的错,没有在开始时指定。对不起!关于实际用例,它有点复杂,所以没有你担心的那么糟糕;-)为什么你的操作符模板化了两次?(在我看来,它像是一个类内实现,第一个模板不应该在那里。)我想应该是模板吗?@wb。不,
Size
是类模板的一个参数。一旦类模板实例化,
Size
是固定的,因此对于实际的操作员来说不再是模板参数。只有在类模板之外实现函数时,才需要添加类的templa除了函数的模板参数之外,te参数也是双模板。但是,代码段中缺少
IntBuffer::
。@wb不,它是模板类的模板赋值运算符,我只是不小心在这里省略了
IntBuffer::
。谢谢@leems指出我的错误。