【C/C++开发】STL内嵌数据类型: value_type

本文详细介绍了STL中value_type的概念及其应用。value_type用于指定容器中元素的类型,如vector<int>::value_type即为int类型。通过实例展示了如何利用value_type定义变量,并将其加入到容器中。

转载自:

【C/C++开发】STL内嵌数据类型: value_type - ZhangPYi - 博客园

使用stl库的时候一直对value_type这个东西理解的不是很好,可以说就是不理解。今天看了《STL源码剖析》才恍然大悟。这里稍作记录。

每个STL中的类都有value_type这种东西,通俗的说value_type 就是stl容器盛装的数据的数据类型,例如:

vector<int> vec;

vector<int>::value_type x;

上述两句代码,第一句是声明一个盛装数据类型是int的数据的vector,第二句是使用vector<int>::value_type定义一个变量x,这个变量x实际上是int类型的,因为vector<int>::value_type中声明的为int型。相应的,假设有:

vector<C> vec;  //假设C是自定义类型

vector<C>::value_type x;

那么第二句定义的变量x的数据类型是C。

每个STL容器类(感觉应该是迭代器类更加准确),都有一句相同的代码:

typede T value_type;

其中T则是类模板中使用的参数 :

template <class T> 

以STL的list容器为例,那么它的类定义就应该有下面的语句:

template<class T>

class list{

publict:

typedef  T  value_type;

//……

};

上述写法,在《STL源码剖析》中称为“声明内嵌型别”技术。

这样一来我们就知道value_type是个什么东西了。接下来就是怎么用啦。

这里要说我的老师真的不怎么滴,对语句

template <class T>

的解释实在是太肤浅啦。我现在也是豁然开朗,这个关键就是class  T。居然这个T可以是一个class,那么value_type也就是可以用来定义class的对象了。所以就可以有下面代码的用法啦:

#include <list>  
#include <vector>  
#include <iostream>  
using namespace std;  
class C{  
public:  
    C(int x){  
        cout << x << endl;  
    }  
    C(){  
        cout << 10 << endl;  
    }  
  
};  
  
void main(){  
    vector<C> vec;  
    C c1,c2(11);  
    vec.push_back(c1);  
    vec.push_back(c2);  
    vector<C>::value_type n1;  
    vector<C>::value_type n2(13);  
    vec.push_back(n1);  
    vec.push_back(n2);  
    cout << vec.size() << endl;  
}  

compile /home/tp/Project/Iford_IMD00V5.1.1/Iford_IMD00V5.1.1/SourceCode/sdk/verify/sample_code/libraries/amigos_ext/commands/amigos_command_base.cpp... /home/tp/Project/Iford_IMD00V5.1.1/Iford_IMD00V5.1.1/SourceCode/sdk/verify/sample_code/../common/stb_truetype/ss_font.cpp: In static member function ‘static SS_Font::FontFile* SS_Font::FontFile::GetIns(const string&)’: /home/tp/Project/Iford_IMD00V5.1.1/Iford_IMD00V5.1.1/SourceCode/sdk/verify/sample_code/../common/stb_truetype/ss_font.cpp:49:104: error: no matching function for call to ‘std::pair<const std::__cxx11::basic_string<char>, std::shared_ptr<SS_Font::FontFile> >::pair(const string&, SS_Font::FontFile*&)’ auto pair = SS_Font::FontFile::map_file_font.insert(MapFileFont::value_type(filepath, font_file)); ^ In file included from /usr/include/c++/5/bits/stl_algobase.h:64:0, from /usr/include/c++/5/bits/char_traits.h:39, from /usr/include/c++/5/string:40, from /usr/include/c++/5/bits/locale_classes.h:40, from /usr/include/c++/5/codecvt:40, from /home/tp/Project/Iford_IMD00V5.1.1/Iford_IMD00V5.1.1/SourceCode/sdk/verify/sample_code/../common/stb_truetype/ss_font.cpp:16: /usr/include/c++/5/bits/stl_pair.h:206:9: note: candidate: template<class ... _Args1, long unsigned int ..._Indexes1, class ... _Args2, long unsigned int ..._Indexes2> std::pair<_T1, _T2>::pair(std::tuple<_Args1 ...>&, std::tuple<_Args2 ...>&, std::_Index_tuple<_Indexes1 ...>, std::_Index_tuple<_Indexes2 ...>) pair(tuple<_Args1...>&, tuple<_Args2...>&, ^ /usr/include/c++/5/bits/stl_pair.h:206:9: note: template argument deduction/substitution failed: /home/tp/Project/Iford_IMD00V5.1.1/Iford_IMD00V5.1.1/SourceCode/sdk/verify/sample_code/../common/stb_truetype/ss_font.cpp:49:104: note: types ‘std::tuple<_Elements ...>’ and ‘const string {aka const std::__cxx11::basic_string<char>}’ have incompatible cv-qualifiers auto pair = SS_Font::FontFile::map_file_font.insert(MapFileFont::value_type(filepath, font_file)); ^ In file included from /usr/include/c++/5/bits/stl_algobase.h:64:0, from /usr/include/c++/5/bits/char_traits.h:39, from /usr/include/c++/5/string:40, from /usr/include/c++/5/bits/locale_classes.h:40, from /usr/include/c++/5/codecvt:40, from /home/tp/Project/Iford_IMD00V5.1.1/Iford_IMD00V5.1.1/SourceCode/sdk/verify/sample_code/../common/stb_truetype/ss_font.cpp:16: /usr/include/c++/5/bits/stl_pair.h:155:9: note: candidate: template<class ... _Args1, class ... _Args2> std::pair<_T1, _T2>::pair(std::piecewise_construct_t, std::tuple<_Args1 ...>, std::tuple<_Args2 ...>) pair(piecewise_construct_t, tuple<_Args1...>, tuple<_Args2...>); ^ /usr/include/c++/5/bits/stl_pair.h:155:9: note: template argument deduction/substitution failed: /home/tp/Project/Iford_IMD00V5.1.1/Iford_IMD00V5.1.1/SourceCode/sdk/verify/sample_code/../common/stb_truetype/ss_font.cpp:49:104: note: cannot convert ‘filepath’ (type ‘const string {aka const std::__cxx11::basic_string<char>}’) to type ‘std::piecewise_construct_t’ auto pair = SS_Font::FontFile::map_file_font.insert(MapFileFont::value_type(filepath, font_file)); ^ In file included from /usr/include/c++/5/bits/stl_algobase.h:64:0, from /usr/include/c++/5/bits/char_traits.h:39, from /usr/include/c++/5/string:40, from /usr/include/c++/5/bits/locale_classes.h:40, from /usr/include/c++/5/codecvt:40, from /home/tp/Project/Iford_IMD00V5.1.1/Iford_IMD00V5.1.1/SourceCode/sdk/verify/sample_code/../common/stb_truetype/ss_font.cpp:16: /usr/include/c++/5/bits/stl_pair.h:150:12: note: candidate: template<class _U1, class _U2, class> constexpr std::pair<_T1, _T2>::pair(std::pair<_U1, _U2>&&) constexpr pair(pair<_U1, _U2>&& __p) ^ /usr/include/c++/5/bits/stl_pair.h:150:12: note: template argument deduction/substitution failed: /home/tp/Project/Iford_IMD00V5.1.1/Iford_IMD00V5.1.1/SourceCode/sdk/verify/sample_code/../common/stb_truetype/ss_font.cpp:49:104: note: types ‘std::pair<_T1, _T2>’ and ‘const string {aka const std::__cxx11::basic_string<char>}’ have incompatible cv-qualifiers auto pair = SS_Font::FontFile::map_file_font.insert(MapFileFont::value_type(filepath, font_file)); ^ In file included from /usr/include/c++/5/bits/stl_algobase.h:64:0, from /usr/include/c++/5/bits/char_traits.h:39, from /usr/include/c++/5/string:40, from /usr/include/c++/5/bits/locale_classes.h:40, from /usr/include/c++/5/codecvt:40, from /home/tp/Project/Iford_IMD00V5.1.1/Iford_IMD00V5.1.1/SourceCode/sdk/verify/sample_code/../common/stb_truetype/ss_font.cpp:16: /usr/include/c++/5/bits/stl_pair.h:144:12: note: candidate: template<class _U1, class _U2, class> constexpr std::pair<_T1, _T2>::pair(_U1&&, _U2&&) constexpr pair(_U1&& __x, _U2&& __y) ^ /usr/include/c++/5/bits/stl_pair.h:144:12: note: template argument deduction/substitution failed: /usr/include/c++/5/bits/stl_pair.h:141:38: error: no type named ‘type’ in ‘struct std::enable_if<false, void>’ template<class _U1, class _U2, class = typename ^ /usr/include/c++/5/bits/stl_pair.h:138:12: note: candidate: template<class _U2, class> constexpr std::pair<_T1, _T2>::pair(const _T1&, _U2&&) constexpr pair(const _T1& __x, _U2&& __y) ^ /usr/include/c++/5/bits/stl_pair.h:138:12: note: template argument deduction/substitution failed: /usr/include/c++/5/bits/stl_pair.h:136:27: error: no type named ‘type’ in ‘struct std::enable_if<false, void>’ template<class _U2, class = typename ^ /usr/include/c++/5/bits/stl_pair.h:133:12: note: candidate: template<class _U1, class> constexpr std::pair<_T1, _T2>::pair(_U1&&, const _T2&) constexpr pair(_U1&& __x, const _T2& __y) ^ /usr/include/c++/5/bits/stl_pair.h:133:12: note: template argument deduction/substitution failed: /home/tp/Project/Iford_IMD00V5.1.1/Iford_IMD00V5.1.1/SourceCode/sdk/verify/sample_code/../common/stb_truetype/ss_font.cpp:49:104: note: cannot convert ‘font_file’ (type ‘SS_Font::FontFile*’) to type ‘const std::shared_ptr<SS_Font::FontFile>&’ auto pair = SS_Font::FontFile::map_file_font.insert(MapFileFont::value_type(filepath, font_file)); ^ In file included from /usr/include/c++/5/bits/stl_algobase.h:64:0, from /usr/include/c++/5/bits/char_traits.h:39, from /usr/include/c++/5/string:40, from /usr/include/c++/5/bits/locale_classes.h:40, from /usr/include/c++/5/codecvt:40, from /home/tp/Project/Iford_IMD00V5.1.1/Iford_IMD00V5.1.1/SourceCode/sdk/verify/sample_code/../common/stb_truetype/ss_font.cpp:16: /usr/include/c++/5/bits/stl_pair.h:128:17: note: candidate: constexpr std::pair<_T1, _T2>::pair(std::pair<_T1, _T2>&&) [with _T1 = const std::__cxx11::basic_string<char>; _T2 = std::shared_ptr<SS_Font::FontFile>] constexpr pair(pair&&) = default; ^ /usr/include/c++/5/bits/stl_pair.h:128:17: note: candidate expects 1 argument, 2 provided /usr/include/c++/5/bits/stl_pair.h:127:17: note: candidate: constexpr std::pair<_T1, _T2>::pair(const std::pair<_T1, _T2>&) [with _T1 = const std::__cxx11::basic_string<char>; _T2 = std::shared_ptr<SS_Font::FontFile>] constexpr pair(const pair&) = default; ^ /usr/include/c++/5/bits/stl_pair.h:127:17: note: candidate expects 1 argument, 2 provided /usr/include/c++/5/bits/stl_pair.h:124:12: note: candidate: template<class _U1, class _U2, class> constexpr std::pair<_T1, _T2>::pair(const std::pair<_U1, _U2>&) constexpr pair(const pair<_U1, _U2>& __p) ^ /usr/include/c++/5/bits/stl_pair.h:124:12: note: template argument deduction/substitution failed: /home/tp/Project/Iford_IMD00V5.1.1/Iford_IMD00V5.1.1/SourceCode/sdk/verify/sample_code/../common/stb_truetype/ss_font.cpp:49:104: note: ‘const string {aka const std::__cxx11::basic_string<char>}’ is not derived from ‘const std::pair<_T1, _T2>’ auto pair = SS_Font::FontFile::map_file_font.insert(MapFileFont::value_type(filepath, font_file)); ^ In file included from /usr/include/c++/5/bits/stl_algobase.h:64:0, from /usr/include/c++/5/bits/char_traits.h:39, from /usr/include/c++/5/string:40, from /usr/include/c++/5/bits/locale_classes.h:40, from /usr/include/c++/5/codecvt:40, from /home/tp/Project/Iford_IMD00V5.1.1/Iford_IMD00V5.1.1/SourceCode/sdk/verify/sample_code/../common/stb_truetype/ss_font.cpp:16: /usr/include/c++/5/bits/stl_pair.h:112:26: note: candidate: constexpr std::pair<_T1, _T2>::pair(const _T1&, const _T2&) [with _T1 = const std::__cxx11::basic_string<char>; _T2 = std::shared_ptr<SS_Font::FontFile>] _GLIBCXX_CONSTEXPR pair(const _T1& __a, const _T2& __b) ^ /usr/include/c++/5/bits/stl_pair.h:112:26: note: no known conversion for argument 2 from ‘SS_Font::FontFile*’ to ‘const std::shared_ptr<SS_Font::FontFile>&’ /usr/include/c++/5/bits/stl_pair.h:108:26: note: candidate: constexpr std::pair<_T1, _T2>::pair() [with _T1 = const std::__cxx11::basic_string<char>; _T2 = std::shared_ptr<SS_Font::FontFile>] _GLIBCXX_CONSTEXPR pair() ^ /usr/include/c++/5/bits/stl_pair.h:108:26: note: candidate expects 0 arguments, 2 provided /home/tp/Project/Iford_IMD00V5.1.1/Iford_IMD00V5.1.1/SourceCode/sdk/verify/sample_code/build/compile.mk:114: recipe for target '/home/tp/Project/Iford_IMD00V5.1.1/Iford_IMD00V5.1.1/SourceCode/sdk/verify/sample_code/../common/stb_truetype/ss_font.user.x86.o' failed make[12]: *** [/home/tp/Project/Iford_IMD00V5.1.1/Iford_IMD00V5.1.1/SourceCode/sdk/verify/sample_code/../common/stb_truetype/ss_font.user.x86.o] Error 1 make[12]: Leaving directory '/home/tp/Project/Iford_IMD00V5.1.1/Iford_IMD00V5.1.1/SourceCode/sdk/verify/sample_code' Makefile:182: recipe for target '../common/stb_truetype_obj_all' failed make[11]: *** [../common/stb_truetype_obj_all] Error 2 make[11]: *** 正在等待未完成的任务.... compile /home/tp/Project/Iford_IMD00V5.1.1/Iford_IMD00V5.1.1/SourceCode/sdk/verify/sample_code/libraries/amigos_ext/commands/amigos_command_instance.cpp... In file included from /usr/include/c++/5/bits/hashtable.h:35:0, from /usr/include/c++/5/unordered_map:47, from /home/tp/Project/Iford_IMD00V5.1.1/Iford_IMD00V5.1.1/SourceCode/sdk/verify/sample_code/libraries/amigos_gencode/amigos_code_printer.h:25, from /home/tp/Project/Iford_IMD00V5.1.1/Iford_IMD00V5.1.1/SourceCode/sdk/verify/sample_code/libraries/amigos_gencode/amigos_gencode_anr.h:20, from /home/tp/Project/Iford_IMD00V5.1.1/Iford_IMD00V5.1.1/SourceCode/sdk/verify/sample_code/libraries/amigos_gencode/amigos_gencode_anr.cpp:15: /usr/include/c++/5/bits/hashtable_policy.h: In instantiation of ‘struct std::__detail::__is_noexcept_hash<stream_type, std::hash<stream_type> >’: /usr/include/c++/5/type_traits:137:12: required from ‘struct std::__and_<std::__is_fast_hash<std::hash<stream_type> >, std::__detail::__is_noexcept_hash<stream_type, std::hash<stream_type> > >’ /usr/include/c++/5/type_traits:148:38: required from ‘struct std::__not_<std::__and_<std::__is_fast_hash<std::hash<stream_type> >, std::__detail::__is_noexcept_hash<stream_type, std::hash<stream_type> > > >’ /usr/include/c++/5/bits/unordered_map.h:100:66: required from ‘class std::unordered_map<stream_type, std::__cxx11::basic_string<char> >’ /home/tp/Project/Iford_IMD00V5.1.1/Iford_IMD00V5.1.1/SourceCode/sdk/verify/sample_code/libraries/amigos/amigos_base/amigos_module_base.h:38:1: required from here /usr/include/c++/5/bits/hashtable_policy.h:85:34: error: no match for call to ‘(const std::hash<stream_type>) (const stream_type&)’ noexcept(declval<const _Hash&>()(declval<const _Key&>()))> ^ 这是MAKE输出的结果,问题在哪,工厂提供的SDK,应该不会有代码错误
最新发布
09-16
<think>好的,我现在需要帮助用户分析他们遇到的编译错误。用户提到这是在使用工厂提供的SDK时出现的错误,所以他们认为问题可能不在代码本身,但需要找出原因。 首先,我仔细阅读了错误日志。第一个错误出现在ss_font.cpp的第49行,涉及std::pair的构造问题。用户提供的代码尝试插入一个键值对到map_file_font中,其中键是filepath(const string),值是font_file(FontFile*指针)。错误信息指出没有匹配的std::pair构造函数,可能类型不匹配。 接下来,我注意到map_file_font的类型是MapFileFont,而value_type应该是std::pair<const string, std::shared_ptr<FontFile>>。但用户代码中传递的是FontFile*,而期望的是shared_ptr。这里的问题可能是将原始指针直接转换为shared_ptr时没有正确处理,导致类型不匹配。 然后,第二个错误在unordered_map的使用中,stream_type可能没有合适的hash函数。这可能是因为stream_type没有定义哈希函数,或者std::hash没有被正确特化,导致编译器无法生成对应的哈希计算函数。 用户提到SDK由工厂提供,可能认为代码没问题,但可能存在的问题是: 1. SDK中的代码可能有类型使用错误,比如应该用shared_ptr却用了原始指针。 2. 缺少必要的头文件或命名空间的使用,导致std::pair构造失败。 3. 编译器版本或标准库版本不兼容,导致某些模板特性无法正确推导。 4. stream_type没有正确的哈希函数,导致unordered_map无法实例化。 可能的解决方案包括: - 检查map_file_font的定义,确认value_type是否正确,是否应该使用shared_ptr。 - 在插入元素时,将FontFile*转换为shared_ptr,例如使用std::shared_ptr<FontFile>(font_file)。 - 确认是否包含了正确的头文件,尤其是涉及智能指针和unordered_map的部分。 - 检查stream_type是否是用户定义类型,是否需要自定义哈希函数,或者是否应该使用其他类型作为键。 - 考虑编译器版本是否过旧,是否需要升级或调整编译选项以支持C++11/14特性。 用户可能没有考虑到的是,即使SDK是官方提供的,也可能存在针对特定编译器版本或标准库的兼容性问题。例如,某些旧版本的GCC对C++11标准的支持不完全,可能导致模板类型推导失败。另外,可能需要检查是否在代码中正确使用了命名空间,或者是否有宏定义影响了类型。 总结来说,主要问题可能出在类型不匹配(原始指针与shared_ptr)以及缺少哈希函数,需要用户检查SDK的使用方式或与供应商确认兼容性。</think>问题出现在代码中尝试将`SS_Font::FontFile*`指针插入`std::map`或`std::unordered_map`时类型不匹配。具体原因如下: 1. **类型不匹配**: `MapFileFont::value_type` 是 `std::pair<const std::string, std::shared_ptr<SS_Font::FontFile>>`,但代码中直接传入了 `SS_Font::FontFile*` 原始指针(`font_file`),未转换为 `std::shared_ptr`。 2. **构造函数无法推导**: `std::pair` 的构造需要匹配的类型,但原始指针无法隐式转换为 `std::shared_ptr`,导致编译器找不到合适的构造函数。 3. **`stream_type` 哈希问题**: 第二个错误表明 `std::unordered_map` 使用的键类型 `stream_type` 缺少有效的 `std::hash` 特化,导致哈希函数调用失败。 --- ### 修复建议 1. **将原始指针转换为 `std::shared_ptr`**: 修改插入逻辑,将 `font_file` 转换为 `std::shared_ptr`: ```cpp auto pair = SS_Font::FontFile::map_file_font.insert( MapFileFont::value_type(filepath, std::shared_ptr<SS_Font::FontFile>(font_file)) ); ``` 或确保 `font_file` 已经是 `std::shared_ptr`。 2. **检查 `stream_type` 的哈希定义**: 为 `stream_type` 自定义哈希函数,或确认是否已正确包含相关头文件: ```cpp namespace std { template<> struct hash<stream_type> { size_t operator()(const stream_type& s) const { // 实现哈希逻辑 } }; } ``` 3. **验证 SDK 兼容性**: 确认编译器版本(如 GCC 5)是否支持 SDK 要求的 C++ 标准(如 C++11/14),或联系 SDK 提供方获取适配补丁。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值