似乎编译器应该能够捕捉到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
一起使用。