3
是否可以將變量函數應用於std :: apply的元組?應用std :: apply的變量函數:: apply
例如,下面的代碼工作正常GCC 6.2.1:
void print_t(std::string i, std::string j) {
std::cout << i << " " << j << std::endl;
}
int main() {
std::tuple<std::string, std::string> t{"ab", "cd"};
std::experimental::apply(print_t, t);
return 0;
}
但是,如果我嘗試應用可變參數函數:
template<typename T>
void vprint(T && t) {
std::cout << std::forward<T>(t) << std::endl;
}
template<typename T, typename ... Ts>
void vprint(T && t, Ts ... ts) {
std::cout << std::forward<T>(t) << " ";
vprint<Ts...>(std::forward<Ts>(ts)...);
}
int main() {
std::tuple<std::string, std::string> t{"fd", "ab"};
std::experimental::apply(vprint, t);
return 0;
}
編譯器抱怨說,它不能推導出模板參數vprint
。好吧,讓我們明確地寫出它們:
std::experimental::apply(vprint<std::string, std::string>, t);
現在,編譯器結束了一些暴露標準庫內部的模糊錯誤。
我在C++ 11中編寫了自己的std::apply
實現,並且我理解爲什麼它不能推導出可變參數函數模板的參數。但是,理論上,std::apply
具有所有扣除所需的信息。
那麼,可變參數函數在GCC6中的應用還沒有實現? C++ 17兼容的編譯器是否允許這樣的應用程序? 如果不是,他們會允許應用實例化的可變參數模板函數,如vprint<std::string, std::string>
?
爲什麼是第二方案更好? 'std :: move'基本上是對右值引用的強制轉換,所以這兩個代碼片段的語義看起來都是相同的。 – Sergey
@Sergey:第二個繼續轉發參數,而第一個強制知道元組類型,可能會修改't'(因爲print_t通過複製傳遞)。 – Jarod42
@Sergey我們假設'print_t'不是您想要調用的唯一函數;並且'std :: string &&'參數可以自由移動。你不會在你的實現中移動它。從語義上講,在移入函數調用之後,沒有人應該依賴'std :: string',但是,除非有強有力的保證(比如'get'提供)。 – Yakk