typeid能用来调用一个带模板的C++函数吗?

huangapple go评论65阅读模式
英文:

Can typeid be used to invoke a templated c++ function

问题

typeid(或其他动态传递类型的方式)能够用于调用一个模板函数吗?

最终,我需要一个转换函数,它将把数据缓冲区从大约十种源类型转换为十种目标类型,这将导致需要静态编码的数百种情况。如果能够传递源类型和目标类型的类型信息,然后自动构建适当的模板函数并调用它,那将非常方便。

以下是演示我尝试实现的简化代码:
```cpp
template<typename T>
void myFunc(T buf, int val) { *buf = val; }

const std::type_info& GetTypeInfo(int csType)
{
  switch(csType)
  {
    case dsCHAR:
    {
      return typeid(char*);
    }
    case dsWCHAR:
    {
      return typeid(wchar_t*);
    }
    default:
    {
      return typeid(int*);
    }
  }
}

void convert(void* buf, int csType, char* src, int len)
{
  const std::type_info& theType = GetTypeInfo(csType);
  for(int ix = 1; ix < len; ix++)
  {
    myFunc<theType>(&dynamic_cast<theType>(buf)[ix], src[ix]); // <- 这无法编译通过
  }
}

使用type_info&与模板或强制转换是不被编译器允许的,我也没有找到绕过这个问题的方法,如果有可能的话。


<details>
<summary>英文:</summary>

Can typeid (or some other way to dynamically pass the type) be used to invoke a templated function.

Ultimately I need a conversion function which will convert data buffers from about a dozen source types to a dozen destination types which leads to hundred cases to statically code.  It would be nice to be able to pass type information for source and destination which would automatically build the appropriate template function and invoke it.

Here is the simplified code that demonstrates what I am trying to do:

template<typename T>
void myFunc(T buf, int val) { *buf = val; }

const std::type_info& GetTypeInfo(int csType)
{
switch(csType)
{
case dsCHAR:
{
return typeid(char*);
}
case dsWCHAR:
{
return typeid(wchar_t*);
}
default:
{
return typeid(int*);
}
}
}

void convert(void* buf, int csType, char* src, int len)
{
const std::type_info& theType = GetTypeInfo(csType);
for(int ix = 1; ix < len; ix++)
{
myFunc<theType>(&dynamic_cast<theType>(buf)[ix], src[ix]); // <- This fails to compile
}
}


Using ```type_info&amp;``` with the template or in a cast is not allowed by the compiler and I have not been able to figure out how to get around it, if it is even possible.


</details>


# 答案1
**得分**: 2

```cpp
首先,你在使用 `dynamic_cast ...`,它是在运行时进行的操作,接下来的指令是一个 `template&lt;typename T&gt; ...` 函数,它在编译时进行的操作!

所以这是不可能的,你需要决定是在运行时还是在编译时执行。

我认为你需要类似这样的东西(`GodLambda` :D)

```cpp
enum CHARS { dsCHAR, dsWCHAR };
using csType = CHARS;
using MyFunc = std::function&lt;bool(void*)&gt;;
std::map&lt;csType, MyFunc&gt; godLambda = {
    {dsCHAR,
     [](void* ptr) -&gt; bool {
       auto theType = reinterpret_cast&lt;char*&gt;(ptr);
       if (nullptr == theType) return false;
       // 我的函数特化:
       return true;
     }},
    {dsWCHAR,
     [](void* ptr) -&gt; bool {
       auto theType = reinterpret_cast&lt;wchar_t*&gt;(ptr);
       if (nullptr == theType) return false;
       // 我的函数特化:
       return true;
     }}
};

<details>
<summary>英文:</summary>

At the first you are using `dynamic_cast ...` and it&#39;s in the runtime, and the next instruction is a function that is `template&lt;typename T&gt; ...` that is in compile time!

so it&#39;s not possible , you should decide do you want to do that in runtime or compile-time.

I think you need something like this(`GodLambda` :D)

```cpp

enum CHARS { dsCHAR, dsWCHAR };
using csType = CHARS;
using MyFunc = std::function&lt;bool(void*)&gt;;
std::map&lt;csType, MyFunc&gt; godLambda = {
    {dsCHAR,
     [](void* ptr) -&gt; bool {
       auto theType = reinterpret_cast&lt;char*&gt;(ptr);
       if (nullptr == theType) return false;
       // my func specialize:
       return true;
     }},
    {dsWCHAR,
     [](void* ptr) -&gt; bool {
       auto theType = reinterpret_cast&lt;wchar_t*&gt;(ptr);
       if (nullptr == theType) return false;
       // my func specialize:
       return true;
     }}
};

huangapple
  • 本文由 发表于 2023年2月10日 11:44:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/75406725.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定