简体   繁体   English

带有歧义标识符的void指针

[英]void pointer cast with ambigious identifiers

Pardon any syntax errors. 原谅任何语法错误。 I have C++ code that is setup similar to this: 我有安装类似于此的C ++代码:

template<typename T>
void addytox(T *x, T *y, int n)
{
   for(int i = 0; i < n; ++i) {
       x[i] += y[i];
   }
   return;
}


void my_func(void *x, void *y, int n, int dtype)
{
   /* Here is where I am unsure of how to do a simple static cast using 
   the dtype identifier. I want to avoid long code using a switch or 
   if/else that would check all possible conditions, for example having 
   code that looks like this:

      if (dtype == 0) {
          addytox((int*)x, (int*)y, n);
      }
      else if (dtype == 1) {
          addytox((float*)x, (float*)y, n);
      }
      else if (dtype == 2) {
          addytox((double*)x, (double*)y, n);
      }
      else {
          //Print/log some error...
          exit;
      }

      return;
   */
}

The reason the code it setup like this is because my_func is pointing to a NumPy array which could of any type (int, float32, float64, etc), and I am calling my_func from Python via ctypes. 之所以这样设置代码,是因为my_func指向可以是任何类型(int,float32,float64等)的NumPy数组,而我正在通过ctypes从Python调用my_func。 I know the C++ will not know what type the NumPy array is, but I can easily get the data type in Python, and pass that into my_func (in this case, integer dtype). 我知道C ++不知道NumPy数组是什么类型,但是我可以轻松地在Python中获取数据类型,并将其传递给my_func(在这种情况下,是整数dtype)。 What I'd like to know is if I could use that identifier an be able to call function addytox only once, with the proper type cast. 我想知道的是,如果我可以使用该标识符,则只能使用正确的类型转换来一次调用addytox函数。

for example: 例如:

addytox((cast_type*)x, (cast_type*)y, n));

Is it possible to do something like this in C++, and if so how would I go about doing it? 是否可以在C ++中执行类似的操作?如果可以,我该怎么做?

Thank you. 谢谢。

Unfortunately as I understand the issue, compile time type determination with templates is not going to help you at run time. 不幸的是,据我所知,使用模板进行编译时类型确定不会在运行时为您提供帮助。 You are pretty much stuck with a switch-type mechanism to determine the type you need to invoke at runtime. 您几乎迷上了使用开关类型机制来确定在运行时需要调用的类型。

HOWEVER, there are some brilliant template metaprogramming techniques that I can share. 但是,我可以分享一些出色的模板元编程技术。 These help bridge the gap between compile and run-time type determination. 这些有助于弥合编译和运行时类型确定之间的差距。

// Generic Declaration. Note the default value.
// For any of the TypeId's not specialized, the compiler will give errors.
template<int TypeId = 0>
struct DispatchAddYToX;

// Specialize for typeId = 0, which let's say is int
template<>
struct DispatchAddYToX<0>  // Let's say TypeId 0 = int
{
    enum { MyId = 0 };
    typedef int MyType;

    void dispatch(void* x, void* y, int n, int dType)
    {
        // Expanded version, for clarity.
        if(dType == MyId)
        {
            // Awriiite! We have the correct type ID.
            // ADL should take care of lookup.
            addYToX((MyType*)x, (MyType*)y, n);
        }
        else
        {
            // If not the correct ID for int, try the next one.
            DispatchAddYToX<MyId + 1>::dispatch(x, y, n, dType);
        }
    }
};

// Specialize for typeId = 1, which let's say is float
template<>
struct DispatchAddYToX<1>  // Let's say TypeId 1 = float
{
    enum { MyId = 1 };
    typedef float MyType;

    void dispatch(void* x, void* y, int n, int dType)
    {
        // Nice and compact version
        (dType == MyId) ? addYToX((MyType*)x, (MyType*)y, n) :
                          DispatchAddYToX<MyId + 1>::dispatch(x, y, n, dType);
    }
};

... 
// And so on for the rest of the type id's.

// Now for a C-style wrapper.
// Use this with your python hook
void addYToXWrapper(void* x, void*y, int n, int dType)
{
    // Defaults to start at 0 (int)
    // Will replace the switch statement.
    DispatchAddYToX::dispatch(x, y, n, dType);
}

So in the end, it's a fancy switch table which does almost the same thing. 最后,它是一个花哨的开关桌,几乎完成了相同的操作。 The interface is much cleaner though, in my opinion :) 不过,我认为该界面更加简洁:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM