似乎编译器应该能够捕捉到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()随机替换为其他任何单词,并且仍然可以编译。我知道正确的方法是拜访。我不可避免地试图拥有一个同时处理地图和多地图的功能,并将其转换为另一种数据结构。
谢谢!
答案 0 :(得分:2)
您的代码会编译,因为yay -S dotnet-sdk
和begin()
是从属名称-它们取决于函数模板参数,因此它们的查找将推迟到end()
模板实例化之前。但是它永远不会被实例化!
如果添加以下内容,则代码将不再编译:
flat
答案 1 :(得分:1)
“编译”是因为该功能是模板。解析基本模板后,此处不会生成任何代码,而且无法进行基本语法检查。
这是因为编译器不知道updated_at
是否包含var_maps<K,V>
。可能会有专长。
实例化begin()
时,即将var_maps
与具体类型var_maps
和K
结合使用时,会收到错误消息。