我正在撰寫一個函式,用它的迭代器來操作一個集合,但它給了我一個錯誤
候選 template 忽略了: couldn't infer template argument
最小可復制的代碼如下:
#include <bit/stdc .h>
using namespace std;
template <typename T>
void foo(typename set<T>:iterator it1)
{
//做一些事情。
}
int main()
{
set<int> aSet;
foo(aSet.begin()); // no matching function call to 'foo'
}
我試著直接包括<set>,改變函式定義的順序,但沒有任何解決方法。最奇怪的是,我把set迭代器作為引數用在其他函式中,它也起作用了。
這些其他的函式宣告是這樣的:
template <typename T>。
void bar(set< T>& aSet, vector<T>& aVector, typename set< T>: :iterator it)。
(這些確切的引數,以這個確切的順序)。
uj5u.com熱心網友回復:
在foo中,引數T typename set<T>::iterator是一個non-duced context:
...用于組成P的型別、模板和非型別值不參與模板引數推導,而是使用在其他地方推匯出來的或明確指定的模板引數。如果一個模板引數只在非推導的背景關系中使用,并且沒有明確指定,那么模板引數推導就會失敗。
T在這種非教育背景下使用,并且沒有在foo中明確指定它應該推導到什么型別,編譯器不能推匯出型別;因此出現了錯誤!
這意味著,如果你在foo中明確提到了什么T,它就會像引文中提到的那樣進行編譯。
foo<int> (aSet. begin()); //compiles!
或者更好的是,將迭代器作為模板引數提供
。template <typename Iterator>
void foo(Iterator it1)
如果你想限制Iterator只用于std::set<T>:iterator,你可以SFINAE/a>函式。下面是一個示例代碼.
#include <type_traits> /std: :enable_if, std::is_same>
#include <iterator> //std::iterator_traits
template<typename Iterator>
inline constexpr bool is_std_set_iterator =
std::is_same_v<Iterator, typename std::set<typename std::iterator_traits<Iterator>:value_type>:iterator> ||
std::is_same_v<Iterator, typename std::set<typename std::iterator_traits<Iterator> ::value_type>:const_iterator>。
template <typename Iterator>
auto foo(Iterator it1) -> std: :enable_if_t<is_std_set_iterator<Iterator>, void>
{
//做一些事情。
}
另一方面,在bar中,編譯器已經推斷出了std::set<int>&aSet的第一個函式引數,并且看到了typename std::set<T>: :iterator,它可以推匯出typename std::set<int>:iterator,因為T已經在前面的函式引數中被推導為int。因此,它是有效的!
作為一個附帶說明,請看下面的內容:
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/316127.html
標籤:
