![](/img/trans.png)
[英]c++ - <unresolved overloaded function type> in function template calling
[英]wrapping template function and <unresolved overloaded function type
我的包裝功能有問題。
template <typename Iter, typename SomeFunction>
void wrap(Iter first, Iter last, SomeFunction someFunction)
{
someFunction(first, last);
}
我想像這樣使用它:
template <typename Iter>
void fill5(Iter first, Iter last)
{
fill(first, last, 5);
}
int main()
{
vector<int> v(100, -1);
wrap(v.begin(), v.end(), fill5);
}
但我明白了
test.cpp: In function ‘int main()’:
test.cpp:16:40: error: no matching function for call to ‘wrap(std::vector<int>::iterator, std::vector<int>::iterator, <unresolved overloaded function type>)’
test.cpp:16:40: note: candidate is:
wrap.h:6:6: note: template<class Iter, class SomeFunction> void wrap(Iter, Iter, someFunction)
我知道如果我會這樣稱呼這個功能
wrap(v.begin(), v.end(), fill5< vector<int>::iterator> );
它會編譯。 但我是否總是要明確這樣做? 太糟糕了。 為什么編譯器無法推斷出將使用哪個函數? 是否有可能編寫wrap函數來獲取第一個參數?
在C ++ 03或C ++ 11中,你無能為力。
fill5
是一個函數模板 ,你不能獲取函數模板的地址。 編譯器將函數模板視為無限重載集,並要求您明確指定要采用以下地址的實例:
wrap(v.begin(), v.end(), fill5<vector<int>::iterator>);
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
或者(正如我在原始帖子的評論中提到的,以及其他答案建議),您可以使用帶有模板化調用運算符的fill5
函數來包裝fill5
的調用。
但是,在C ++ 14中,我們可以做得更好:我們可以使用通用lambdas來簡化一些事情。 如果您定義此宏:
#define WRAP(f) \
[&] (auto&&... args) -> decltype(auto) \
{ return f (std::forward<decltype(args)>(args)...); }
然后你可以寫:
int main()
{
std::vector<int> v(100, -1);
wrap(v.begin(), v.end(), WRAP(fill5));
}
這是一個實例 。
另一種方法是使用仿函數:
class fill5
{
public:
template <typename Iter>
void operator () (Iter first, Iter last) const
{
std::fill(first, last, 5);
}
};
int main( int, char ** )
{
std::vector<int> v(100, -1);
wrap(v.begin(), v.end(), fill5);
return 0;
}
因為fill是一個模板函數,所以基本上存在無限數量的重載,編譯器不知道選擇哪一個。
如果你聲明你的第二個模板參數來描述一個帶有2個Iter類型參數的函數,那么它就可以推導出它。 以下示例有效,看起來就像您想要的那樣。 它並不像你的嘗試那樣通用。 它確保被調用的函數返回void並且需要2個Iter參數。
template <typename Iter >
void wrap( Iter first, Iter last, void(*someFunction)(Iter,Iter) )
{
someFunction( first, last );
}
template <typename Iter>
void fill5(Iter first, Iter last)
{
fill(first, last, 5);
}
int main( int, char ** )
{
std::vector<int> v(100, -1);
wrap(v.begin(), v.end(), fill5);
return( 0 );
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.