10

我正在围绕遗留 API编写C++包装器。这个 API 为我提供了一个指针值来保存额外的数据,我想用它来实现小缓冲区优化

我已经实现了一个is_small_pod 元函数来检查给定类型是否是POD并且它是否适合void*

template< typename Type >
struct is_small_pod
  : std::integral_constant<
        bool
      , std::is_pod< Type >::type::value
        && sizeof( Type ) <= sizeof( void* )
    >
{};

我正在设置这样的值:

// void*& param;
if( detail::is_small_pod< Type >() )
{
    *static_cast< Type* >( &param ) = value;
} else {
    param = new Type( value );
}

我是否正确实施了这种优化?我相信当值对齐与指针的对齐不兼容时,这将失败(可能是奇怪的角落情况)。这种情况甚至可能,还是我只是想多了?我应该如何扩展我的元功能以检查兼容的对齐方式

4

2 回答 2

8

类型的对齐方式不可能大于该类型的大小。

3.11 对齐[basic.align]

[...]对齐是实现定义的整数值,表示可以分配给定对象的连续地址之间的字节数。

5.3.3 大小[expr.sizeof]

2 - [...] n元素数组的大小是元素大小的n倍。

因此,您的代码只能中断 if alignof(void *) < sizeof(void *),而在大多数平台上并非如此。

为了安全起见,你可以写:

template< typename Type >
struct is_small_pod
  : std::integral_constant<
        bool
      , std::is_pod< Type >::type::value
        && sizeof( Type ) <= sizeof( void* )
        && alignof( Type ) <= alignof( void* )
    >
{};
于 2012-10-25T21:14:46.190 回答
0

就像一般方法一样,您始终可以尝试测试您的理论。我想你会做这样的事情:

template< class Type >
bool TestAlignmentSanity( Type value )
{
    // This function is only valid for small POD types
    if( !detail::is_small_pod< Type >() )
        return false;

    // Temporary space covering alignments spanning the size of a void*
    const int nBytes = sizeof(void*);
    char buffer[sizeof(Type) + nBytes - 1];

    // For each target alignment, test that a copy is successful.
    for( int i = 0; i < nBytes; i++ )
    {
       Type * target = static_cast< Type* >( &buffer[i] );

       // Sanity-check that the pointer was actually aligned as we requested
       if( (char*)target != &buffer[i] ) return false;

       // Copy and test that the result is as expected.  Assumes '==' operator
       // is defined...  Otherwise, implement with byte comparisons.
       *target = value;
       if( !(*target == value) ) return false;
    }

    return true;
}

在这里,我测试了数据类型可以复制到任何跨越 a 大小的对齐方式中void*。这只是一个想法。=)

于 2012-10-25T21:17:58.033 回答