根据数据返回不同的数据类型(C++)

Joe*_*oel 9 c++ return-value

反正有没有做过这样的事情?

(correct pointer datatype) returnPointer(void* ptr, int depth)
{

    if(depth == 8)
        return (uint8*)ptr;
    else if (depth == 16)
        return (uint16*)ptr;
    else
        return (uint32*)ptr;
}
Run Code Online (Sandbox Code Playgroud)

谢谢

bdo*_*lan 10

不可以.C++函数的返回类型只能根据显式模板参数或其参数类型而有所不同.它不能根据其参数的而变化.

但是,您可以使用各种技术来创建一个类型,该类型是其他几种类型的并集.不幸的是,这不一定对你有所帮助,因为一种这样的技术本身就是无效的,回到原始类型将是一种痛苦.

但是,通过内部解决问题,您可能会得到您想要的.我想你会想要使用你发布的代码,例如:

void bitmap_operation(void *data, int depth, int width, int height) {
  some_magical_type p_pixels = returnPointer(data, depth);
  for (int x = 0; x < width; x++)
    for (int y = 0; y < width; y++)
      p_pixels[y*width+x] = some_operation(p_pixels[y*width+x]);
}
Run Code Online (Sandbox Code Playgroud)

因为C++需要在编译时知道p_pixels的类型,所以这不会按原样工作.但是我们能做的是让bitmap_operation本身成为一个模板,然后用一个基于深度的开关包装它:

template<typename PixelType>
void bitmap_operation_impl(void *data, int width, int height) {
  PixelType *p_pixels = (PixelType *)data;
  for (int x = 0; x < width; x++)
    for (int y = 0; y < width; y++)
      p_pixels[y*width+x] = some_operation(p_pixels[y*width+x]);
}

void bitmap_operation(void *data, int depth, int width, int height) {
  if (depth == 8)
    bitmap_operation_impl<uint8_t>(data, width, height);
  else if (depth == 16)
    bitmap_operation_impl<uint16_t>(data, width, height);
  else if (depth == 32)
    bitmap_operation_impl<uint32_t>(data, width, height);
  else assert(!"Impossible depth!");
}
Run Code Online (Sandbox Code Playgroud)

现在,编译器将为您自动为bitmap_operation_impl生成三个实现.

  • 最接近的C++必须是一个对象类型是void*.还有boost的变体类型. (3认同)

sth*_*sth 7

如果可以使用模板参数而不是普通参数,则可以创建模板化函数,为每个depth值返回正确的类型.首先,根据需要对正确的类型进行一些定义depth.您可以为不同的位大小定义具有特化的模板:

// template declaration
template<int depth>
struct uint_tmpl;

// specializations for certain types
template<> struct uint_tmpl<8>  { typedef uint8_t type; };
template<> struct uint_tmpl<16> { typedef uint16_t type; };
template<> struct uint_tmpl<32> { typedef uint32_t type; };
Run Code Online (Sandbox Code Playgroud)

此定义可用于声明模板化函数,该函数为每个位值返回正确的类型:

// generic declaration
template<int depth>
typename uint_tmpl<depth>::type* returnPointer(void* ptr);

// specializations for different depths
template<> uint8_t*  returnPointer<8>(void* ptr)  { return (uint8_t*)ptr;  }
template<> uint16_t* returnPointer<16>(void* ptr) { return (uint16_t*)ptr; }
template<> uint32_t* returnPointer<32>(void* ptr) { return (uint32_t*)ptr; }
Run Code Online (Sandbox Code Playgroud)

  • 与没有像returnPointer8(),returnPointer16()和returnPointer32()这样的模板的解决方案相比,这没有任何优势,因为模板参数必须是常量(即程序员已知). (2认同)
  • 在编译时必须知道模板参数是模板的一般属性。这仍然比不同命名的函数更灵活,例如你可以定义类似 template&lt;int depth&gt; ptadd(void* ptr, int val) { *returnPointer&lt;depth&gt;(ptr) += val; }. 这适用于所有深度。使用不同命名的 returnPointer 函数,您还需要声明几个单独的 ptadd 变体。对于模板化版本,一个 ptadd 函数就足够了。 (2认同)