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

时间:2014-06-16 15:28:48

标签: 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 < b1

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

2 个答案:

答案 0 :(得分:2)

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

但是,如果您仍然想要这样做,那么您可以创建自己的复制赋值运算符。你必须编写自己的static_assert(但你肯定可以在C ++ 98中这样做,因为你已经完成了它),因为你明确排除了这两个我知道的地方有一个已经为你编写和调试的地方(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.
}

答案 1 :(得分:1)

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

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

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