簡體   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