C++ 为什么std::variant使用开始和结束迭代器编译?
编译器似乎应该能够捕捉到std::variant没有迭代器方法这一事实,但我的代码编译起来似乎没有问题(即使我随机为变量编写方法或成员变量),但它在运行时崩溃(这是理所当然的)。有人能解释一下为什么要编译这段代码吗 注意:这并没有阻止进程,因为现在我使用的是std::visit,但是如果知道为什么要编译它,那就太好了 我尝试过使用不同的变体模式,它们都可以编译。参见代码示例。您可以将其弹出到cppreferences或godbolt中,它应该使用C++17或更高的标志进行编译C++ 为什么std::variant使用开始和结束迭代器编译?,c++,std-variant,C++,Std Variant,编译器似乎应该能够捕捉到std::variant没有迭代器方法这一事实,但我的代码编译起来似乎没有问题(即使我随机为变量编写方法或成员变量),但它在运行时崩溃(这是理所当然的)。有人能解释一下为什么要编译这段代码吗 注意:这并没有阻止进程,因为现在我使用的是std::visit,但是如果知道为什么要编译它,那就太好了 我尝试过使用不同的变体模式,它们都可以编译。参见代码示例。您可以将其弹出到cppreferences或godbolt中,它应该使用C++17或更高的标志进行编译 #include
#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 ) )
{
}
}
#包括
#包括
#包括
#包括
#包括
#包括
模板
//使用var_maps=std::variant;
//使用var_maps=std::variant;
使用var_maps=std::variant;
模板
空平面(常量变量映射和vmap)
{
//对于(auto-bIter=vmap.bexxxgin(),eIter=vmap.end();bIter!=eIter;
对于(auto-bIter=vmap.begin(),eIter=vmap.end();bIter!=eIter;
bIter=vmap.上限(bIter->first))
{
}
}
我最初使用的是maps,但它可以有效地编译任何东西。此外,我可以将begin()随机替换为任何其他单词,它仍然可以编译。我知道正确的方法是访问。我不可避免地尝试使用一个函数来处理map和multimap,并将其转换为另一个数据结构
谢谢!它“编译”,因为函数是一个模板。在这里,除了基本语法检查之外,没有生成任何代码。解析模板时,无法完成任何检查
这是因为编译器不知道var\u映射是否包含begin()
当您实例化var\u映射时,您将收到错误,即对具体类型K
和V使用var\u映射
,因为begin()
和end()
是依赖名称-它们依赖于函数模板参数,因此它们的查找被推迟到平面
模板实例化。但它从未被实例化
如果添加以下内容,代码将不再编译:
int main () {
&flat<int, int>;
}
int main(){
&平坦的;
}
我明白了,所以所有模板化的方法都被推迟到实例化(不管类型如何)。我不明白的是,std::variant永远不会有一个开始和结束迭代器,对吗?这实际上什么时候起作用?我想我不能在K和V中放置任何类型,使variant有一个开始和结束方法?