C 库 - 用于C++:重定义,不同的类型修饰符
C library - use in C++: redefinition, different type modifiers
我最近用纯C构建了一个CSV库。头文件如下所示:
#ifndef CSV_H
#define CSV_H
#include "unicode/ustdio.h"
#include "unicode/uchar.h"
#include "unicode/ucsdet.h"
#include "unicode/ustring.h"
#define T CSV_T
typedef struct T *T;
extern T CSV_new(char *filename);
extern void CSV_free(T *csv);
extern int CSV_length(T csv);
extern void CSV_print_info(T csv);
extern UChar **CSV_get_header(T csv);
extern UChar ***CSV_get_values(T csv);
extern long CSV_get_num_columns(T csv);
extern long CSV_get_num_lines(T csv);
extern char *CSV_get_charset(T csv);
#undef T
#endif
结构CSV_T的实际定义是在代码文件中完成的,以隐藏实现。我经常使用纯C在不同的项目中使用该库,没问题。现在我想在使用C++构建的 GUI 应用程序中重用代码,并收到以下错误消息:
Error C2373 'CSV_T': redefinition; different type modifiers ... xxxProjectsLibCSVLibCSVcsv.h 10
C++处理与 C 不同的 typedef 吗?不知何故令人困惑,...
以下是您的 MCVE 应该是什么样子:
typedef struct T *T;
这是一个完整的单行源文件,可重现问题且没有依赖项。没有宏,没有标头,没有不必要的代码。
g++ -std=c++14 -O2 -Wall -pedantic -pthread main.cpp && ./a.out
main.cpp:1:19: error: conflicting declaration 'typedef struct T* T'
typedef struct T *T;
^
main.cpp:1:16: note: previous declaration as 'struct T'
typedef struct T *T;
^
它在 C 中工作的原因是T
还不是结构的名称;你需要struct
前缀。
在C++中,这不是真的,因为首先不需要struct
前缀。一旦你声明T
是一个类(令人困惑的是,你在typedef
本身就是这样做的!),你不能只给其他类型(你试图用typedef
创建的那个)相同的名称。
反正你在做什么很奇怪,CSV_T
的意思是struct CSV_T*
.我建议干脆不要这样做。
如果您只是坚持使用typedef struct CSV_T CSV_T
那么这将适用于两种语言,但尝试使用相同的名称制作不同的类型是行不通的。
C++标准的附录C说:
7.1.3
更改:C++ typedef 名称必须不同于在同一作用域中声明的任何类类型名称(除非 typedef 是具有相同名称的类名的同义词)。在 C 中,在同一作用域中声明的 typedef 名称和结构标记名称可以具有相同的名称(因为它们具有不同的命名空间)。
例:
typedef struct name1 { /.../ } name1; // valid C and C++ struct name { /.../ }; typedef int name; // valid C, invalid C++
理由:为了便于使用,C++ 在对象声明或类型强制转换中使用时,不要求类型名称以关键字 class、struct 或 union 为前缀。
例:
class name { /.../ }; name i; // i has type class name
对原始特征的影响:删除语义明确定义的特征。
转换难度:语义转换。必须重命名 2 种类型之一。
使用范围有多广:很少。
- 有没有一种方法可以通过"typedef"为重新定义的基本类型定义特征和强制转换运算符
- 强枚举类型定义:Clang Bug 还是 C++11 标准不确定性?
- 列表参数的类型定义
- 使用模板化的键类型定义 std::map,该键类型基于作为参数接收的函数
- 关于 C++ 中的函数类型定义
- C++(和 ROS) - 包含与前向声明引用,设置默认值和类型定义
- 将使用/类型定义限制为类范围
- 模板类型定义?
- C++:模板类的类型定义
- 如何对命名空间限定类型进行类型定义?
- 此递归模板类型定义是否有效C++?
- 具有调整对齐方式的类型定义
- C++从抽象类型定义类成员
- 用于C++代码的 API 监视器类型定义 (XML)
- 如何将result_of与函数类型定义一起使用
- 在C++的适当类型定义位置
- 如何根据模板类型定义浮点常量?
- 如何为缺少预定义运算符而不扩展命名空间"std"的标准类型定义运算符>> (istream &, ...)?
- 参数化类的别名(或类型定义)内部类
- 如果我想从类型"T"定义元素的容器(来自 STL),那么"T"必须使用默认构造函数?