[英]Type deduction of const references in templated functions
下面我有一個名為ProxyCall的模板函數,它接受一個對象,一個成員函數及其參數。 它只是將調用轉發給成員函數。
我希望能夠在不使用模板限定符的情況下調用該函數(想象大量此類調用具有多個參數)。 當我嘗試傳遞const引用參數時,類型推導主要起作用,但編譯器(msvc和gcc 4.9)都是barf。
#include <string>
struct Widget {
void f(const std::string& s, bool b) {}
};
template<typename T, typename... Args>
void ProxyCall(T &obj, void(T::*method)(Args...), Args&&... args) {
(obj.*method)(std::forward<Args>(args)...);
}
int main(int argc, char* argv[])
{
Widget w;
std::string s;
ProxyCall<Widget, const std::string&, bool>(w, &Widget::f, s, true); // OK
ProxyCall(w, &Widget::f, (const std::string&)s, true); // also OK
ProxyCall(w, &Widget::f, s, true); // ERROR: template parameter is ambiguous
return 0;
}
我的問題是:如何修改上面的代碼,以便編譯器自動推導出類型,而無需借助顯式模板限定符或顯式轉換。 考慮到編譯器已經從Widget :: f的簽名中知道確切的參數類型,這似乎應該是可能的。
template<typename T, typename... Args>
void ProxyCall(T &obj, void(T::*method)(Args...), Args&&... args) {
(obj.*method)(std::forward<Args>(args)...);
}
Args
是從ProxyCall
的第二個參數和尾隨參數推導出來的。
在第三種情況下,因為s
不是const
,所以Args
被推導為[std::string&, bool]
(回想一下參考折疊和轉發引用的規則)。 但是,成員函數簽名明顯不同。 因此,在Args
中推導出第一種類型的兩種不同類型,這導致演繹失敗。
相反,為了ref-qualifiers,使參數類型和參數獨立 - 並轉發object參數:
template<typename T, typename F, typename... Args>
void ProxyCall(T&& obj, F method, Args&&... args) {
(std::forward<T>(obj).*method)(std::forward<Args>(args)...);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.