在不同大小的缓冲区之间复制,这些缓冲区按其固定大小进行模板化

Copying between different sized buffers that are templated by their fixed size

本文关键字:缓冲区 之间 复制      更新时间:2023-10-16

简化版本是这样的:

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

编辑:看来我应该更清楚...如果由于提到的大小约束行为而不允许赋值,我想导致编译时错误。 同样没有提升,理想情况下对可能没有完全 C++11 支持的编译器(如 MSVC 2010(友好。

首先让我说,在我看来,你应该这样做并不直观。如果我正在阅读代码并看到它,我会想知道如果目标缓冲区大小大于源缓冲区大小,OTHER 元素会发生什么(它们会被保留吗?它们会被清除吗?它们会以其他非确定性的方式改变吗?不仅如此,如果您将其限制为相同大小的缓冲区,编译器生成的复制构造函数和复制赋值运算符将正常工作,您无需进行额外的工作。

但是,如果毕竟您仍然想这样做,则可以创建自己的复制赋值运算符。你必须编写自己的static_assert(但你当然可以在 C++98 中做到这一点,因为 boost 已经做到了(,因为你已经明确排除了我知道的两个地方,以获得一个已经为你编写和调试的地方(C++11 和 boost(。

运算符可能如下所示:

template <int Size> template <int RightSize>
IntBuffer<Size>& IntBuffer<Size>::operator=(const IntBuffer<RightSize>& right)
{
    static_assert(RightSize <= Size);
    // The real work.
}

一种可能性是使用模板重载赋值运算符,该模板将另一个缓冲区的大小作为参数。在实现中,如果可以使用 C++11,则可以static_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)
}

如果由于编译器限制而无法使用 C++11 的功能(不需要完整 C++11(,也可以使用基于 SFINAE 的方法,但在这种情况下无法发出描述性错误消息:

template<int OtherSize>
typename enable_if<OtherSize <= Size, IntBuffer<Size> &>::type
//                 ^---------------^  ^---------------^
//                    requirement        return type
operator=(const IntBuffer<OtherSize> &other) {
    // (implementation)
}

其中enable_if只是 std::enable_if 的可能实现的副本(如果您使用 pre-C++11(:

template<bool B, class T = void>
struct enable_if {};
template<class T>
struct enable_if<true, T> { typedef T type; };

(来源:http://en.cppreference.com/w/cpp/types/enable_if(

演示:http://ideone.com/uXGo5E