C++报错解决:error: ‘int’ is not a class, struct, or union type typedef typename _Sequence::value_

这篇博客详细记录了作者在使用C++编程时遇到的一个错误:尝试错误地typedef一个内置类型'int',导致编译器报错。错误信息表明'int'不是类、结构体或联合类型。通过提供正确的typedef声明方式,作者解决了这个问题。

我在使用C++的时候,遇到了如下报错:

-> % g++ test.cpp
In file included from /usr/include/c++/7/queue:64:0,
                 from test.cpp:5:
/usr/include/c++/7/bits/stl_queue.h: In instantiation ofclass std::queue<int, int>:
test.cpp:33:21:   required from here
/usr/include/c++/7/bits/stl_queue.h:124:47: error: ‘int’ is not a class, struct, or union type
       typedef typename _Sequence::value_type  value_type;
                                               ^~~~~~~~~~
/usr/include/c++/7/bits/stl_queue.h:125:46: error: ‘int’ is not a class, struct, or union type
       typedef typename _Sequence::reference  reference;
                                              ^~~~~~~~~
/usr/include/c++/7/bits/stl_queue.h:126:51: error: ‘int’ is not a class, struct, or union type
       typedef typename _Sequence::const_reference const_reference;
                                                   ^~~~~~~~~~~~~~~
/usr/include/c++/7/bits/stl_queue.h:127:46: error: ‘int’ is not a class, struct, or union type
       typedef typename _Sequence::size_type  size_type;
                                              ^~~~~~~~~

使用clang编译的话报错更不容易懂:

-> % clang++ test.cpp 
In file included from test.cpp:5:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/7.4.0/../../../../include/c++/7.4.0/queue:64:
/usr/bin/../lib/gcc/x86_64-linux-gnu/7.4.0/../../../../include/c++/7.4.0/bits/stl_queue.h:124:24: error: type 'int' cannot be used
      prior to '::' because it has no members
      typedef typename  _Sequence::value_type           value_type;
                        ^
test.cpp:33:21: note: in instantiation of template class 'std::queue<int, int>' requested here
    queue<int, int> q;
                    ^
In file included from test.cpp:5:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/7.4.0/../../../../include/c++/7.4.0/queue:64:
/usr/bin/../lib/gcc/x86_64-linux-gnu/7.4.0/../../../../include/c++/7.4.0/bits/stl_queue.h:125:24: error: type 'int' cannot be used
      prior to '::' because it has no members
      typedef typename  _Sequence::reference            reference;
                        ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/7.4.0/../../../../include/c++/7.4.0/bits/stl_queue.h:126:24: error: type 'int' cannot be used
      prior to '::' because it has no members
      typedef typename  _Sequence::const_reference      const_reference;
                        ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/7.4.0/../../../../include/c++/7.4.0/bits/stl_queue.h:127:24: error: type 'int' cannot be used
      prior to '::' because it has no members
      typedef typename  _Sequence::size_type            size_type;
                        ^
4 errors generated.

报错是因为我错误地声明了:

queue<int, int> q;

正确的声明方法如下:

queue<int> q;
queue <pair<int, int> > q2; 
1>F:\updateVPC\vpc2_newest\vms\vms-public\src\others\interprocess\Interproc\InterprocSerialization.h(86,5): error C2672: “PackageParamsImpl”: 未找到匹配的重载函数 1>(编译源文件“../../../src/others/interprocess/Interface/MediaWindowControllerInterface.cpp”) 1> F:\updateVPC\vpc2_newest\vms\vms-public\src\others\interprocess\Interproc\InterprocSerialization.h(78,6): 1> 可能是“void InterprocSerialization::PackageParamsImpl(boost::archive::binary_oarchive &,const Tuple &,std::integer_sequence<size_t,_Kx...>)” 1> F:\updateVPC\vpc2_newest\vms\vms-public\src\others\interprocess\Interproc\InterprocSerialization.h(86,5): 1> “void InterprocSerialization::PackageParamsImpl(boost::archive::binary_oarchive &,const Tuple &,std::integer_sequence<size_t,_Kx...>)”: 无法从“boost::fusion::detail::make_index_sequence<1>”推导出“std::integer_sequence<size_t,_Kx...>”的 模板 参数 1> F:\updateVPC\vpc2_newest\vms\vms-public\src\others\interprocess\Interproc\InterprocSerialization.h(86,5): 1> 模板实例化上下文(最早的实例化上下文)为 1> F:\updateVPC\vpc2_newest\vms\vms-public\src\others\interprocess\Interface\MediaWindowControllerInterface.cpp(52,29): 1> 查看对正在编译的函数 模板 实例化“void InterprocSerialization::PackageParams<int>(boost::archive::binary_oarchive &,const std::tuple<int> &)”的引用 1>IPCAPPDownloader.cpp 1>IPCAppEnterpriseListContext.cpp 1>F:\updateVPC\vpc2_newest\vms\vms-public\vms-client\SurveillanceSystem\SurveillanceSystem\widget\preview\PreviewViewScaleWidget.h(20,9): warning C4005: “SCALE_IMAGE_PICTUR_MIN_HEIGHT”: 宏重定义 1>(编译源文件“../../../src/others/interprocess/Interproc/TPFunctionBindUtils.cpp”) 1> F:\updateVPC\vpc2_newest\vms\vms-public\vms-client\SurveillanceSystem\SurveillanceSystem\widget\preview\PreviewScaleImageWidget.h(20,9): 1> 参见“SCALE_IMAGE_PICTUR_MIN_HEIGHT”的前一个定义 1>F:\updateVPC\vpc2_newest\vms\vms-public\vms-client\SurveillanceSystem\SurveillanceSystem\widget\preview\PreviewViewScaleWidget.h(21,9): warning C4005: “SCALE_IMAGE_PICTUR_MIN_WIDTH”: 宏重定义 1>(编译源文件“../../../src/others/interprocess/Interproc/TPFunctionBindUtils.cpp”) 1> F:\updateVPC\vpc2_newest\vms\vms-public\vms-client\SurveillanceSystem\SurveillanceSystem\widget\preview\PreviewScaleImageWidget.h(21,9): 1> 参见“SCALE_IMAGE_PICTUR_MIN_WIDTH”的前一个定义 1>F:\updateVPC\vpc2_newest\vms\vms-public\vms-client\SurveillanceSystem\SurveillanceSystem\widget\preview\PreviewViewScaleWidget.h(20,9): warning C4005: “SCALE_IMAGE_PICTUR_MIN_HEIGHT”: 宏重定义 1>(编译源文件“../../../src/others/interprocess/Interproc/TPWindowControllerEntry.cpp”) 1> F:\updateVPC\vpc2_newest\vms\vms-public\vms-client\SurveillanceSystem\SurveillanceSystem\widget\preview\PreviewScaleImageWidget.h(20,9): 1> 参见“SCALE_IMAGE_PICTUR_MIN_HEIGHT”的前一个定义 1>F:\updateVPC\vpc2_newest\vms\vms-public\vms-client\SurveillanceSystem\SurveillanceSystem\widget\preview\PreviewViewScaleWidget.h(21,9): warning C4005: “SCALE_IMAGE_PICTUR_MIN_WIDTH”: 宏重定义 1>(编译源文件“../../../src/others/interprocess/Interproc/TPWindowControllerEntry.cpp”) 1> F:\updateVPC\vpc2_newest\vms\vms-public\vms-client\SurveillanceSystem\SurveillanceSystem\widget\preview\PreviewScaleImageWidget.h(21,9): 1> 参见“SCALE_IMAGE_PICTUR_MIN_WIDTH”的前一个定义 1>IPCAppExcutorBasicCloud.cpp 1>F:\updateVPC\vpc2_newest\vms\vms-public\vms-client\SurveillanceSystem\SurveillanceSystem\widget\preview\PreviewViewScaleWidget.h(20,9): warning C4005: “SCALE_IMAGE_PICTUR_MIN_HEIGHT”: 宏重定义 1>(编译源文件“../../../src/context/IPCAppContext.cpp”) 1> F:\updateVPC\vpc2_newest\vms\vms-public\vms-client\SurveillanceSystem\SurveillanceSystem\widget\preview\PreviewScaleImageWidget.h(20,9): 1> 参见“SCALE_IMAGE_PICTUR_MIN_HEIGHT”的前一个定义 1>F:\updateVPC\vpc2_newest\vms\vms-public\vms-client\SurveillanceSystem\SurveillanceSystem\widget\preview\PreviewViewScaleWidget.h(21,9): warning C4005: “SCALE_IMAGE_PICTUR_MIN_WIDTH”: 宏重定义 1>(编译源文件“../../../src/context/IPCAppContext.cpp”) 1> F:\updateVPC\vpc2_newest\vms\vms-public\vms-client\SurveillanceSystem\SurveillanceSystem\widget\preview\PreviewScaleImageWidget.h(21,9): 1> 参见“SCALE_IMAGE_PICTUR_MIN_WIDTH”的前一个定义 1>F:\updateVPC\vpc2_newest\vms\vms-public\src\others\interprocess\Interproc\InterprocSerialization.h(57,61): error C2672: “GetTuple”: 未找到匹配的重载函数 1>(编译源文件“../../../src/others/interprocess/Interproc/TPFunctionBindUtils.cpp”) 1> F:\updateVPC\vpc2_newest\vms\vms-public\src\others\interprocess\Interproc\InterprocSerialization.h(28,7): 1> 可能是“Tuple InterprocSerialization::GetTuple(boost::archive::binary_iarchive *,std::integer_sequence<size_t,_Kx...>)” 1> F:\updateVPC\vpc2_newest\vms\vms-public\src\others\interprocess\Interproc\InterprocSerialization.h(57,61): 1> “Tuple InterprocSerialization::GetTuple(boost::archive::binary_iarchive *,std::integer_sequence<size_t,_Kx...>)”: 无法从“boost::fusion::detail::make_index_sequence<1>”推导出“std::integer_sequence<size_t,_Kx...>”的 模板 参数 1> F:\updateVPC\vpc2_newest\vms\vms-public\src\others\interprocess\Interproc\InterprocSerialization.h(57,61): 1> 模板实例化上下文(最早的实例化上下文)为 1> F:\updateVPC\vpc2_newest\vms\vms-public\src\others\interprocess\Interproc\TPFunctionBindUtils.cpp(55,23): 1> 查看对正在编译的函数 模板 实例化“InterprocError InterprocMsgManager::Subscribe<void(int)>(const std::string,R (__cdecl *),const std::string)”的引用 1> with 1> [ 1> R=void (int) 1> ] 1> F:\updateVPC\vpc2_newest\vms\vms-public\src\others\interprocess\Interproc\InterprocMsgManager.h(22,16): 1> 查看对正在编译的函数 模板 实例化“long InterprocListener::RegisterCallback<R>(std::string,R (__cdecl *))”的引用 1> with 1> [ 1> R=void (int) 1> ] 1> F:\updateVPC\vpc2_newest\vms\vms-public\src\others\interprocess\Interproc\InterprocListener.h(26,27): 1> 查看对正在编译的函数 模板 实例化“void InterprocSerialization::Bind<R>(std::map<std::string,std::function<void (boost::archive::binary_oarchive *,boost::archive::binary_iarchive *)>,std::less<std::string>,std::allocator<std::pair<const std::string,std::function<void (boost::archive::binary_oarchive *,boost::archive::binary_iarchive *)>>>> &,std::string,R (__cdecl *))”的引用 1> with 1> [ 1> R=void (int) 1> ] 1> F:\updateVPC\vpc2_newest\vms\vms-public\src\others\interprocess\Interproc\InterprocSerialization.h(73,34): 1> 查看对正在编译的函数 模板 实例化“void InterprocSerialization::CallProxy<R>(R (__cdecl *),boost::archive::binary_oarchive *,boost::archive::binary_iarchive *)”的引用 1> with 1> [ 1> R=void (int) 1> ] 1> F:\updateVPC\vpc2_newest\vms\vms-public\src\others\interprocess\Interproc\InterprocSerialization.h(65,5): 1> 查看对正在编译的函数 模板 实例化“void InterprocSerialization::CallProxy_<void,int>(R (__cdecl *)(int),boost::archive::binary_oarchive *,boost::archive::binary_iarchive *)”的引用 1> with 1> [ 1> R=void 1> ] 这是我的源码: #pragma once #include <map> #include <string> #include <functional> #include <boost/archive/binary_iarchive.hpp> #include <boost/archive/binary_oarchive.hpp> #include <boost/fusion/support/detail/index_sequence.hpp> #include <tuple> #include <boost/serialization/vector.hpp> namespace InterprocSerialization { template<typename T> struct type_transfer { typedef T type; }; template<> struct type_transfer<void> { typedef int type; }; template< typename ... T > using index_sequence_for = boost::fusion::detail::make_index_sequence< sizeof ... (T) >; template<typename... Params> std::tuple<typename std::decay<Params>::type...> MakeTuple(Params... ps) { return std::make_tuple(ps...); } template<typename Tuple, std::size_t... I> Tuple GetTuple(boost::archive::binary_iarchive* ia, boost::fusion::detail::index_sequence<I...>) { Tuple t; std::initializer_list<int>{ ((*ia >> std::get<I>(t)), 0)... }; return t; } template<typename R, typename... Params, typename Tuple, std::size_t... Index > typename R invoke(R(*f)(Params...), Tuple&& t, boost::fusion::detail::index_sequence<Index...>) { return f(std::get<Index>(std::forward<Tuple>(t))...); } template<typename R, typename F, typename ArgsTuple> typename std::enable_if<std::is_same<R, void>::value, typename type_transfer<R>::type>::type CallHelper(F f, ArgsTuple args) { invoke(f, args, boost::fusion::detail::make_index_sequence<std::tuple_size<typename std::decay<ArgsTuple>::type>::value>{}); return 0; } template<typename R, typename F, typename ArgsTuple> typename std::enable_if<!std::is_same<R, void>::value, typename type_transfer<R>::type>::type CallHelper(F f, ArgsTuple args) { return invoke(f, args, boost::fusion::detail::make_index_sequence<std::tuple_size<typename std::decay<ArgsTuple>::type>::value>{}); } template<typename R, typename... Params> void CallProxy_(R(*f)(Params... ps), boost::archive::binary_oarchive* oa, boost::archive::binary_iarchive* ia) { std::tuple<typename std::decay<Params>::type...> args = GetTuple<std::tuple<typename std::decay<Params>::type...> >(ia, boost::fusion::detail::make_index_sequence<sizeof...(Params)>()); typename type_transfer<R>::type ret = CallHelper<R>(f, args); } template<typename R> void CallProxy(R(*f), boost::archive::binary_oarchive* oa, boost::archive::binary_iarchive* ia) { CallProxy_(f, oa, ia); } template<typename R> void Bind(std::map<std::string, std::function<void(boost::archive::binary_oarchive*, boost::archive::binary_iarchive*)> > &handlers, std::string fname, R(*f)) { // todo ����У�� handlers[fname] = std::bind(&CallProxy<R>, f, std::placeholders::_1, std::placeholders::_2); } template<typename Tuple, std::size_t... Is> void PackageParamsImpl(boost::archive::binary_oarchive& oa, const Tuple& t, boost::fusion::detail::index_sequence<Is...>) { std::initializer_list<int>{ ((oa << std::get<Is>(t)), 0)... }; } template<typename... Args> void PackageParams(boost::archive::binary_oarchive& oa, const std::tuple<Args...>& t) { PackageParamsImpl(oa, t, index_sequence_for<Args...>{}); } } // namespace InterProSerialization 为什么会报错???
最新发布
11-11
<think>我们正在处理一个编译错误:'int' is not a class, struct, or union type 根据用户提供的引用[^1],它展示了嵌套结构体的指定初始化器(designated initializers)的使用。在C++中,指定初始化器允许我们按照成员声明的顺序使用成员名称来初始化结构体或类的成员。 错误信息通常意味着我们试图以访问类、结构体或联合体成员的方式(例如使用点运算符.)来访问一个非聚合类型的变量(比如int)。例如,如果我们有一个整数变量,却试图使用.运算符访问它的成员,就会产生这个错误。 分析用户提供的代码片段: 引用[^1]中给出了两个初始化例子: Person p1{.name{.first = "John", .last = "Doe"}, .age = 30}; // 正确 // Person p2{.age = 30, .name{.first = "John"}}; // 错误:顺序不对 第二个初始化被注释掉并标记为错误,因为指定初始化器要求初始化的顺序必须与成员声明的顺序一致。但是,这个错误并不是我们当前要处理的错误。 当前用户的错误是:'int' is not a class, struct, or union type。这个错误通常发生在以下情况: 1. 试图将一个基本类型(如int)当作一个类/结构体来使用,例如使用成员访问运算符(.)访问其成员。 2. 在函数调用或初始化时,错误地使用了不正确的类型。 例如,假设有以下代码: int x = 5; x.some_member; // 错误:因为int是基本类型,没有成员 或者,在结构体初始化时,如果成员类型不匹配,也可能导致类似错误。例如: struct A { int a; }; struct B { A a; int b; }; B b = { .a = { .a = 1 }, .b = 2 }; // 正确 B b2 = { .a = 1, .b = 2 }; // 错误?实际上这里不会直接报这个错误,因为1可以赋值给A类型的成员吗?不行,因为A是一个结构体,而1是整数,所以会报无法用int初始化A。 但是,如果我们在初始化时错误地使用了嵌套的指定初始化器,而实际上某个成员是基本类型,却试图用初始化结构体的方式初始化它,就会导致错误。 例如: struct Person { int id; Name name; }; // 错误示例:试图用初始化结构体的方式初始化id(基本类型int) Person p3 = { .id = { .num = 123 }, .name = { .first="John", .last="Doe" } }; // 这里.id后面跟了一个花括号,试图初始化一个不存在的结构体,因为id是int,不是结构体。 因此,错误的原因可能是:在初始化或访问成员时,将一个基本类型(如int)当作结构体或类来处理,即使用了成员访问运算符或使用了嵌套的初始化器。 如何修复? 1. 检查错误发生处的代码,确认哪个变量被当作结构体/类使用了,但实际上它是基本类型。 2. 如果是初始化问题,确保对基本类型的成员直接赋值,而不是使用嵌套的初始化器。 3. 如果是成员访问,则检查该变量的类型,确保它确实是类/结构体类型。 根据用户提供的引用[^1]中的例子,我们也可以注意到,指定初始化器要求顺序一致,并且嵌套的初始化器只能用于聚合类型(结构体、类、数组等)。 因此,针对用户的问题,我们给出以下解释和修复步骤: 解释: 该错误意味着在代码中,我们尝试使用点运算符(.)访问一个类型为`int`的变量的成员,但是`int`是基本类型,不是类、结构体或联合体,因此没有成员可以访问。 可能的原因: 1. 错误地认为一个基本类型的变量是一个结构体或类。 2. 在初始化一个结构体时,对基本类型的成员使用了嵌套的初始化器(即花括号),而实际上应该直接赋值。 修复方法: 检查代码中使用了点运算符的地方,确保左边的表达式是一个类、结构体或联合体类型。如果是在初始化时,确保基本类型的成员直接使用等号赋值,而不是嵌套初始化。 举例: 错误代码: struct Info { int id; struct { std::string first; std::string last; } name; }; Info info = { .id = { .num = 12345 }, // 错误!因为id是int类型,不能用花括号初始化,更不能用.num(因为int没有成员) .name = { .first = "John", .last = "Doe" } }; 正确代码: Info info = { .id = 12345, // 直接赋值 .name = { .first = "John", .last = "Doe" } }; 另外,如果错误发生在其他地方,比如: int x = 10; x.value = 5; // 错误:'int' is not a class, struct, or union type 那么需要检查为什么将x当作结构体使用,并修改代码。 如果用户能够提供具体的代码片段,我们可以更精确地定位问题。但根据目前的信息,我们只能给出一般性的解释和修复方法。 生成相关问题: 1. 在C++中,指定初始化器的使用有哪些限制? 2. 如何正确初始化嵌套结构体? 3. 为什么在C++中不能给基本类型(如int)添加成员? 4. 如何避免在结构体初始化时出现类型不匹配的错误?</think>### 解释与修复:`'int' is not a class, struct, or union type` 错误 #### 错误原因 此错误表示**尝试以访问类/结构体成员的方式访问基本数据类型(如 `int`)**。根本原因通常包括: 1. **成员访问错误**:对非聚合类型(如 `int`)使用 `.` 运算符访问成员 2. **初始化顺序问题**:在指定初始化器(designated initializers)中**违反成员声明顺序** 3. **类型不匹配**:将基本类型当作结构体初始化 #### 修复方法(基于引用[^1]示例) ```cpp struct Name { std::string first, last; }; struct Person { Name name; int age; }; // ✅ 正确:顺序匹配声明 (name → age) Person p1{.name{.first = "John", .last = "Doe"}, .age = 30}; // ❌ 错误原因1:初始化顺序错误 (age → name) Person p2{.age = 30, .name{.first = "John"}}; // 触发编译错误 // ❌ 错误原因2:将int当作结构体初始化 Person p3{.name{.first = "Jane", .last = "Smith"}, .age{.value = 25}}; // 错误:'age'是int类型,不能用{.value=...}初始化 ``` #### 关键修复步骤 1. **检查`.`运算符左侧对象**: ```cpp int num = 10; num.value = 5; // 错误:int不是类/结构体 ``` → 解决方案:确保左侧是自定义类型(非基本类型) 2. **严格遵循初始化顺序**(C++20起强制要求): ```cpp // 错误:.age 必须在 .name 之后 Person p4{.age = 30, .name{"Alice", "Li"}}; // 正确:与声明顺序一致 Person p5{.name{"Bob", "Zhang"}, .age = 40}; ``` 3. **区分基本类型与结构体初始化语法**: ```cpp // ✅ 基本类型直接赋值 .age = 30 // ❌ 禁止对基本类型使用嵌套初始化器 .age{ .value = 30 } ``` #### 深层原理 - **指定初始化器规则**(C++20):初始化顺序必须严格匹配成员声明顺序[^1] - **类型系统限制**:基本数据类型(`int`/`float`等)无成员变量,不支持`.`运算符 - **编译器行为**:Clang/GCC会明确提示错误位置: ``` error: 'int' is not a class, struct, or union type .age{.value=30} ^ ``` --- ### 相关问题 1. 为什么C++的指定初始化器要求严格的成员顺序? 2. 如何调试“成员访问类型不匹配”错误? 3. C++20中的指定初始化器与C语言的初始化器有何区别? 4. 当结构体包含联合体(union)成员时,初始化规则会有什么变化? [^1]: 引用自用户提供的结构体初始化示例,展示了顺序敏感性和类型匹配要求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值