繁体   English   中英

为什么std :: variant用begin和end迭代器编译?

[英]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时会收到错误,即使用具有类型KV var_maps

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM