[英]Why does a std::variant compile with begin and end iterators?
似乎编译器应该能够捕获std :: variant没有迭代器方法的事实,但似乎我的代码编译没有问题(即使我随机组成变量的方法或成员变量),但它在运行时崩溃(理所当然)。 有人可以解释为什么这个代码编译?
注意:这不会阻止进度,因为现在我正在使用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()替换为任何其他单词,它仍然可以编译。 我知道正确的方法是访问。 我不可避免地尝试使用一个处理map和multimap的函数,并将其转换为另一个数据结构。
谢谢!
您的代码编译,因为begin()
和end()
是依赖名称 - 它们依赖于函数模板参数,因此它们的查找被推迟到flat
模板实例化。 但它永远不会被实例化!
如果添加以下内容,则代码将不再编译:
int main () {
&flat<int, int>;
}
它“编译”因为函数是一个模板。 这里没有生成代码,除了基本语法检查之外,在解析模板时不能进行完整的检查。
这是因为编译器不知道var_maps<K,V>
包含begin()
。 可能有专业化。
实例化var_maps
时会收到错误,即使用具有类型K
和V
var_maps
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.