为什么 std::variant 使用开始和结束迭代器进行编译?
Why does a std::variant compile with begin and end iterators?
似乎编译器应该能够捕捉到std::varial没有迭代器方法的事实,但似乎我的代码编译没有问题(即使我随机为变体编造方法或成员变量(,但它在运行时崩溃(理所当然(。有人可以阐明为什么编译此代码吗?
注意:这不会阻碍进度,因为现在我正在使用 std::visit,但很高兴知道为什么要编译。
我尝试使用不同的变体模式,它们都可以编译。请参阅代码示例。你可以把它弹出到 cppreferences,或者 godbolt,它应该使用 C++17 个标志或更高
#include <variant>
#include <string>
#include <cassert>
#include <iostream>
#include <list>
#include <map>
template<typename K, typename V>
//using var_maps = std::variant<std::map<K,V>, std::multimap<K,V> >;
//using var_maps = std::variant<std::list<int>, std::list<float> >;
using var_maps = std::variant<int, float>;
template <typename K, typename V>
void flat( const var_maps<K,V>& vmap)
{
//for(auto bIter = vmap.bexxxgin(), eIter = vmap.end(); bIter != eIter;
for(auto bIter = vmap.begin(), eIter = vmap.end(); bIter != eIter;
bIter = vmap.upper_bound( bIter->first ) )
{
}
}
我最初的案例是地图,但它可以有效地编译任何东西。此外,我可以随机将 begin(( 替换为任何其他单词,它仍然可以编译。我知道正确的方法是访问。我不可避免地试图让一个函数同时处理映射和多映射并将其转换为另一种数据结构。
谢谢!
代码将进行编译,因为begin()
和end()
是依赖名称 - 它们依赖于函数模板参数,因此它们的查找将推迟到flat
模板实例化。但它永远不会实例化!
如果添加以下内容,则代码将不再编译:
int main () {
&flat<int, int>;
}
它"编译"是因为函数是一个模板。此处不会生成任何代码,除了基本的语法检查之外,解析模板时无法进行完整的检查。
这是因为编译器不知道var_maps<K,V>
是否包含begin()
。可能有专业化。
当您实例化var_maps
时,您将收到错误,即将var_maps
与具体类型K
和V
一起使用。
相关文章:
- 编译时二叉搜索树错误的反向迭代器表示"no matching function call for operator=()"
- 编译错误 std::vector<std::shared_ptr<T>>迭代器和擦除方法
- 如果我在下面的代码中使用 list 而不是 vector,为什么在我尝试在迭代器之间执行减法的行中编译失败?
- C++向量迭代器nth_element编译错误
- 为什么 std::variant 使用开始和结束迭代器进行编译?
- 在将迭代器与C 中的null进行比较时,编译误差
- 编译错误与迭代器取消引用的 decltype
- 使用set<set>迭代器的编译错误<int>
- 通过迭代器调用功能无法在派生对象上编译
- C :多态容器 /迭代器与编译时间概念 /特征
- 迭代器使用的编译时验证
- 从函数返回 ::迭代器不会编译
- 二叉树编译错误的迭代器
- C++:使用clang编译以迭代器为值的映射时出现巨大错误
- C++ - 未编译的对象向量的迭代器
- 编译错误 ::向量 ::迭代器
- 链表迭代器模板中的编译错误
- 取消引用字符串迭代器无法编译
- Clang 3.0 C++ std::map<>::迭代器编译错误
- 使用映射迭代器编译错误