简体   繁体   English

C中使用void *的C中的模板

[英]Templates in C using void * in C++

I have a generic class written in C++ and as an exercise, I've been attempting to port it to C. I've tried typedef to specific types but realized it was probably the wrong way to go about it. 我有一个用C ++编写的泛型类,作为练习,我一直在尝试将其移植到C。我尝试将typedef转换为特定类型,但意识到这样做可能是错误的方法。 I'm attempting to use void pointers however i realized i have noway to instantiate the generic class is their something i am missing? 我正在尝试使用void指针,但是我意识到我无法实例化泛型类是我缺少的东西吗?

ctrie.h ctrie.h

#ifndef _COM_WORDGAME_UTILITY_TRIE_H_KYLE
#define _COM_WORDGAME_UTILITY_TRIE_H_KYLE
#ifdef __cplusplus
extern "C"{ //this is used to identify following code as C specific code which will enforce C style name mangling
#endif


typedef struct Trie Trie;

//Create new Trie Object
Trie* newTrie(void * defVal);
//return number of key-value pairs
int size(Trie * t);
//return default value set by user
void * getDefaultValue(Trie * t);
//Check if returned value is not equal to default value
bool contains(Trie * t,const char * key);
//Return Value
void * get(Trie * t,char * key);
//Insert String into symbol Table
void put(Trie * t,char * s,void * val);
//Find and return longest prefix of s in TST
char * longestPrefix(Trie * t,char * s);
//compress the table making it immutable returning the number of nodes removed
int compress(Trie * t);

#ifdef __cplusplus
#include "cTrie.cpp"//quick hack to add cTrie without linking
}
#endif
#endif

ctrie.cpp ctrie.cpp

#include "Trie.hpp" //C++ code
#include "Trie.h" //C code

extern "C"{
using namespace com::wordgame::utility::trie;

//Create new Trie Object
Trie* newTrie(void * defVal){
    return new Trie<typeid(defVal)>(defVal);    
};
//return number of key-value pairs
int size(Trie * t){}
//return default value set by user
void * getDefaultValue(Trie * t){}
//Check if returned value is not equal to default value
bool contains(Trie * t,const char * key){}
//Return Value
void * get(Trie * t,char * key){}
//Insert String into symbol Table
void put(Trie * t,char * s,void * val){}
//Find and return longest prefix of s in TST
char * longestPrefix(Trie * t,char * s){}
//compress the table making it immutable returning the number of nodes removed
int compress(Trie * t){}


}

One of the key advantages of templated container types in C++ is the ability to provide a nice syntactic way to embed the relevant object into the structure itself, so for example a typical std::vector<T> (which is typically implemented as a simple array) can have the stride of a T . C ++中模板容器类型的主要优点之一是能够提供一种将相关对象嵌入结构本身的良好语法方法,例如典型的std::vector<T> (通常以简单的方式实现)。数组)的步幅T To accomplish something like this in C, you would need to either implement your entire function as a bunch of macros, and then "Instantiate" the function set for each type, for example, a simple "Vector" implementation in C might look like this (which is either ugly, beautiful, or satanic depending on who you ask) 为了在C语言中完成类似的工作,您需要将整个函数实现为一堆宏,然后“实例化”每种类型的函数集,例如,C语言中的简单“ Vector”实现可能看起来像这样(这是丑陋的,美丽的还是撒旦的,取决于您问的是谁)

#define VECTORFUNCS(T) \
  typedef struct { \
    T* arr; \
    size_t narr; \
    size_t capacity; \
  } VECTOROF_##T; \
  \
  void vector_##T##_reserve(VECTOROF_##T *v, size_t n) { \
    // \
  } \
  const T* vector_##T##_at(VECTOROF_##T *v, size_t ix) { \
    return v->arr[ix]; \
  } \

VECTORFUNCS(int)
VECTORFUNCS(struct sockaddr)

// etc. //等

As a side note, this could also be implemented much more "cleanly" (depending on who you ask) by simply passing the sizeof(T) and using a single set of functions for any implementation; 附带说明一下,也可以通过简单地传递sizeof(T)并对任何实现使用一组函数来更“干净”地实现(取决于您要求的人)。 the functions would need to treat the arr element as a char* and properly determine the offsets for various operations). 函数需要将arr元素视为char*并适当确定各种操作的偏移量)。

However, if all your template class does is attach a pointer to T for type safety, you may do this entirely in C without much hassle, except of course that you don't get to "instantiate" the template each time (and is also not as necessary. C makes casting from void much less annoying). 但是,如果您的所有模板类都为类型安全附加了指向T的指针,则可以完全用C来完成此操作,而不必麻烦,除非您不必每次都“实例化”模板(并且C使得从空洞中进行投射变得不那么烦人了。

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

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